Vercel无服务器函数与CloudFlare Workers

2021-03-26 20:05:42

Vercel为无服务器函数提供了一个良好的固体解决方案,并使他们的创作过程无缝和无忧无虑.CloudFlare工人提供更多功能,提供更多的功能(例如钥匙值数据存储,Cron),看起来更加成熟和复杂。 。

我所有的结论和调查结果都是基于Vercel和CloudFlare提供的官方文件,也基于我对两个平台的经验。我保留了错误的权利。如果您发现,请告诉我。

自从Moiva开发开始以来一直在使用Vercel。它有助于快速启动和开发Moiva。我非常感谢Vercel的开发商,他们在那里做得很好。

在本质上,Vercel是一种解决静态网站的解决方案,以将静态网站用于全球数据中心网络。 Vercel不会在那里停止,为无服务器函数提供解决方案,该函数可以真正变得非常壮观。

随着Moiva的进一步发展,我累积了一系列要求对Vercel的无服务函数,不幸的是,没有见到。因此,我环顾四周,发现了cloudflare工人。我试一试,我喜欢它。两周后,我的任何无法函数都在那里迁移。

CloudFlare Worker基本上是一个用于将无服务功能部署到世界各地数据中心网络的平台。他们的文档表示,工人也可以用于部署静态应用程序,但我还没有查看它或评估它。我知道CloudFlare还在努力解决静态应用程序的部署/托管 - CloudFlare页面。

在Vercel和CloudFlare工人中处理无服务器函数请求的高级别图片是不同的。我认为从每个平台如何工作和突出差异的说明开始比较是有道理的。

首先,两个平台都使用跨全球分布的数千台服务器的所谓边线网络。

在CloudFlare工人在部署期间的每个功能都会在每个数据中心复制。每个请求都是负载平衡并路由到最近的数据中心,执行该功能并将响应发送回用户。

这里有很重要的是,即使响应已缓存,也很重要。缓存在更深的粒度水平上工作:

开发人员可以利用CloudFlare的缓存API缓存响应并在进一步的请求中使用它。在重量计算的情况下,它可以特别方便。

Vercel在自由中没有复制其网络上的功能,Pro帐户 - 只能部署到一个特定区域。企业计划用户可以为无要函数指定多个区域。

类似于CloudFlare,每个请求都被路由到最近的数据中心。这里相似之处并正在处理以下步骤:

如果数据中心具有用于该请求的缓存,则将缓存的响应立即发送给用户。该函数未执行。请求处理完成。

如果数据中心没有函数,那么它找到了最近的数据中心,并将其转发到那里。

原始服务器缓存响应(根据开发人员指定的标题)并将响应发送回用户。

速度是无服务器功能的重要特征。通过提供对用户的响应所需的时间来衡量。

其中一个成员是旅行时间。请求花费越少的时间越好。

如上所述,CloudFlare工人将每个请求路由到最近的数据中心处理它并发送回复。 CloudFlare表示,其网络跨越100多个国家的200多个城市。这保证了最少的旅行时间。

来自Cloudflare网站的屏幕截图,其中包含世界地图,显示CloudFlare网络数据中心的位置

Vercel的网络密集较小,跨越少于20个地点。这意味着在平均请求上会花费更多时间旅行.Oround,请求将仅在预先存在的缓存的快乐案例中结束。其他时候,如上所述,请求将转发到包含该功能的数据中心。它减少了拥有全球数据中心网络的所有优点。

请求/函数执行时间是速度的另一个主要组成部分。它很大程度上取决于是否存在缓存数据。

CloudFlare工作者始终执行功能是否有缓存数据。另一方面,Vercel从未执行该功能如果它具有有效的缓存数据。我们可以想象它会影响执行时间,但不会显着,因为CloudFlare限制了它(有关详细信息,请参阅下面的限制部分)。

在没有缓存的数据的情况下,执行时间取决于运行时环境的启动速度和在可用的运行时等内存和CPU上的资源以及函数是“热”或“冷”(仅适用于Vercel)。

CloudFlare在罩下使用Google的V8引擎,并在V8隔离的上下文中执行功能。 CloudFlare声称其方法比其他功能实现更有效,并消除了虚拟机模型的冷启动:

工人流程能够通过为每个工人函数调用创建隔离来运行基本上无限的脚本,几乎没有单独的开销。任何给定的隔离物都可以比容器或虚拟机上的节点进程快左右左右开始。值得注意的是,在启动隔离上消耗了较少的内存量级。

Vercel使用云提供商Amazon和Google来执行功能,本身支持NodeJS,Go,Python和Ruby环境。热/冷靴在这里申请:

如果此后随后发生后续请求,则该函数重新用于新调用(热启动)

云提供商允许各种不同大小的功能,但我们已选择一个与使冷启动实例化对齐的函数,几乎瞬间用于用户的工作负载(例如服务HTTP流量)

如果使用Vercel部署您的网站,那么添加新的无服务器函数就像添加新的NodeJS Express的脚本一样简单(或用不同的语言脚本写入)/ API文件夹.Vercel无操作函数也在本地工作Dev Environce Out-Box.Vercel在此实现了伟大的开发人员体验(DX)。

如果您使用Vercel进行网站部署,但希望使用CloudFlare工人无服务器(如我),然后您需要学习和处理更多的东西:

如果您使用和设置自定义域或CloudFlare提供的域

CloudFlare提供了许多易于遵循的示例和“启动器”(GitHub存储库)为不同用例提供了真正的文档。它还提供了用于预览,调试和开发功能的游乐场。我发现它非常有用,经常使用它。

Vercel的缓存配置仅限于在函数响应上设置缓存控制标题。 Vercel建议不要使用浏览器缓存,但依赖于Vercel的网络缓存。因此,配置大部分用于设置缓存时间。此外,有一堆关于可以使用高速缓存时的限制(例如,响应状态代码和请求方法,请求标题)。

当提供缓存的响应时,Vercel不会有机会对缓存响应执行并执行任何更改,或者例如记录请求。

每个新部署Vercel都会自动使缓存无效。因此,如果需要使缓存无效,则开发人员需要重新部署其应用程序。

CloudFlare提供了更灵活和更精细的缓存配置,并具有不同的心理模型,了解缓存应该如何工作。

大多数时间函数都没有繁重的计算,他们花时间大多等待来自子句的响应。

识别出来,CloudFlare在每个请求上运行函数,并为出站函数子句提供自动缓存。开发人员可以通过提供某些配置来修改子requests缓存行为。

我认为每次都在每个请求中运行功能是一个非常重要的功能,区分CloudFlare工人从Vercel区分。它允许您对第三方服务进行记录并具有一些分析。

CloudFlare也涵盖了函数确实具有繁重计算的情况。开发人员可以访问缓存API来存储功能响应并在将来的请求中使用它。开发人员可以自由定义如何以及何时缓存,何时使用以及何时删除缓存值,在发送响应之前可以自由修改缓存值。 CloudFlare提供了良好的文档和示例。

async函数handlerequest(事件){const request = event.request const cacheull = new url(request.url)//从缓存url const cachekey = new请求(cacheull.tostring(),请求)const cache = caches.default //检查值是否已在Cache //(如果没有)中是否已有,则需要从原点获取它,并将其存储在缓存//中以供将来访问响应=等待Cache.match(CacheKey) if(!响应){//如果不在缓存中,从原点响应获取它=等待获取(请求)//必须使用响应构造函数继承所有响应响应=新响应=新响应(响应。响应。 )//缓存API尊重缓存控制标题。将s-max-age设置为10 //将限制在缓存中的响应10秒max //此处对响应所做的任何更改将反映在缓存值response.headers.append("缓存 - 控制&#34 ;," s-maxage = 10")//将获取的响应存储为cachekey //使用waitUntil,这样您就可以返回响应而不阻止//编写到缓存事件.waituntil(缓存。 PUT(CacheKey,Response.Clone())))}返回响应}

CloudFlare无服务器功能具有非常好的独特功能 - 他们可以访问全局,低延迟的键值数据存储。对该商店的更改传播到所有其他边缘位置,并变得全局可见。该商店不会替换数据库,但在某些情况下很好地工作。我认为它是全球可用的缓存。该商店还可以手动(通过CLI接口)或部署期间预先填充。开发人员可以定义一生的值,以确保它们在某个时刻自动丢弃。

CloudFlare仅支持一个运行时 - Chrome的V8。因此,它支持本身支持JavaScript。对于像Kotlin,PHP,Python这样的语言,可以将程序编译为JavaScript。因此,开发人员也可以在这些语言中编写功能,他们只需要编辑JavaScript步骤。

CloudFlare也不会在那里停止并为Web组件提供支持。这意味着还可以使用C,C ++,Rust等汇编语言来编写功能。

Vercel还允许使用不同语言创建自定义运行时。有一些社区运行时间可以提供官方Vercel的建议:Bash,Deno,PHP和Rust。

Vercel对计划任务没有内置支持,并建议使用第三方服务。

通常需要以非阻塞方式与第三方服务进行通信 - 您向用户发送响应,并并行地将数据发送到某些第三方服务,例如,收集一些统计数据。

无服务器函数的问题是它们的生命周期非常有限,可能会在处理通信之前关闭运行时关闭。

CloudFlare提供了一个WaitUntil()挂钩,通知运行时等待运行时间长于发送响应所需的时间的任务。例如,使用它来将数据写入缓存。

if(!响应){//如果不在缓存中,从原点响应获取它=等待获取(请求)//必须使用响应构造函数继承所有响应响应=新响应=新响应(响应。响应。 )//缓存API尊重缓存控制标题。将s-max-age设置为10 //将限制在缓存中的响应10秒max //此处对响应所做的任何更改将反映在缓存值response.headers.append("缓存 - 控制&#34 ;," s-maxage = 10")//将获取的响应存储为cachekey //使用waitUntil,这样您就可以返回响应而不阻止//编写到缓存事件.waituntil(缓存。 PUT(CacheKey,Response.Clone())))}返回响应

在Vercel的函数中,我试图将记录错误设置为Sentry和将数据记录到某些数据库,但它不可预测地运行 - 有时它有时它还没有。日志中也有奇怪的错误。我花了时间意识到问题是,一旦发送响应,运行时停止工作。

值得注意的是,即使在底层容器热,也无法留下运行任务。如果返回响应时的​​子进程运行,则整个容器将被冻结。当发生新的调用时,如果重复使用容器,则它是未冷冻的,允许子进程继续运行。

另一个关于我发现的vercel的问题是您无法真正将所有请求记录到函数中的所有请求,并在其顶部构建分析,因为在请求存在缓存的响应时未执行函数。我找不到它的解决方案。 CloudFlare没有这样的问题,因为它的函数总是在每个请求上执行。

函数脚本的实际运行时没有限制。相反,CPU运行时有限制:自由计划上的10ms,捆绑计划上的50ms。履行子requests的时间不计算在没有处理和CPU是空闲的。

CloudFlare Workers自由地围绕所有,但受到一些限制,主要是读/写入键值(kV)存储,限制kV存储(1 GB)以及CPU运行时限制为10毫秒。

5美元/月的最低收费捆绑计划包括免费的一切,加上CPU运行时(50毫秒)增加,并访问增加的KV存储和读/写。 最终价格由真正的使用定义。 Vercel的自由计划在可用资源方面是慷慨的(1个地区限制除外),但仅限于非商业用途。 Pro计划每位团队成员20美元/月,可以从Github组织中完成一些团队协作功能和部署。