分享到

导言

无服务器范式代表了应用程序和 Web 开发人员与基础设施、语言运行时和补充服务交互方式的显着转变。它通过抽象化并负责许多传统上影响代码在生产环境中运行方式的环境因素,让您可以自由地专注于您的主要关注领域。

虽然无服务器计算有很多好处,但它也存在一些挑战,在您取得成功之前必须承认或解决这些挑战。在本指南中,我们将讨论当前一代解决方案的一些主要痛点,并讨论它们的含义以及您可能如何解决这些问题。您应该对可能需要满足的要求以及可能遇到的障碍有更好的了解。

冷启动问题

使用无服务器时最常讨论的挑战之一称为冷启动问题。虽然无服务器的目标是允许按需立即执行函数,但在某些情况下可能会导致可预测的延迟。

什么是冷启动问题?

无服务器的一个主要卖点是能够在没有活动期间扩展到零。如果函数未被主动执行,则函数的资源将被关闭,从而将容量返回到平台并降低用户保留这些组件的成本。从成本角度来看,这是理想的,因为它意味着用户只需为代码实际执行的时间和资源付费。

这样做的不利之处在于,当资源完全关闭时,下次需要执行时会出现可预测的延迟。需要重新分配资源来运行该函数,这需要时间。最终,最近使用过的“热”函数具有一组性能特征,而需要等待平台创建执行环境的“冷”函数则具有另一组性能特征。

开发人员如何尝试解决冷启动问题?

开发人员和平台已经尝试了多种方法来解决这个问题。一些开发人员计划“虚拟”请求,以使与其功能相关的资源保持待命状态。许多平台已在其服务中添加了额外的层,以允许开发人员自动保持资源待命状态。

这些解决方案开始有点模糊了构成无服务器环境的界限。当开发人员被迫为代码未主动执行时的待命资源付费时,这会引发一些关于无服务器范式基本主张的问题。

最近一种替代预分配资源的方案是通过切换到更轻量级的运行时环境来回避问题。像 V8 这样的运行时具有与传统无服务器截然不同的执行策略,并且能够通过使用不同的隔离技术和更精简的环境来避免冷启动问题。它们以牺牲与依赖于更强大环境的功能的兼容性为代价,避免了冷启动问题。

应用程序设计约束

无服务器模型的另一个基本挑战是它施加的应用程序设计。无服务器平台仅对可以在其约束范围内工作的应用程序有用。其中一些是云计普遍存在的,而另一些要求则是由无服务器模型专门规定的。

设计云友好的架构

应用程序要使用无服务器平台必须满足的第一个要求是以云友好的方式设计。在本文的讨论背景下,至少这意味着应用程序必须至少部分部署到云服务,以便其他组件能够与之通信。虽然可以在设计中实现单体函数,但无服务器模型最适合微服务架构

这样做的好处是,您的应用程序必须部分设计为由您的无服务器提供商执行的一系列函数。您必须习惯于在您不控制的基础设施上进行处理。此外,您必须能够将应用程序的功能分解为可以远程执行的离散函数。

处理无状态执行

无服务器函数在设计上是无状态的。这意味着,虽然如果使用相同的资源执行函数,某些信息可能会被缓存,但您不能依赖于函数调用之间共享任何状态。

您必须设计您的函数,使其具有内部执行所需的所有信息。任何外部状态都必须在调用开始时获取,并在完成前导出。由于函数可能是并行执行的,这也限制了可以合理操作的状态类型。一般来说,您的函数必须管理的状态越少,它们的执行速度就越快、成本就越低,您需要管理的复杂性也就越低。

函数的短暂性还有其他副作用。如果您的函数需要连接到数据库系统,则很可能很快就会耗尽数据库的连接池。由于函数的每次调用都可以在不同的上下文中执行,因此当数据库响应不同的调用或尝试将其资源返回到其池时,数据库的连接池可能会迅速耗尽。像 Prisma Accelerate 这样的解决方案通过管理无服务器实例的连接资源(在任何连接池之上)来帮助缓解这些问题。

供应商锁定问题

使用无服务器时难以摆脱的一个挑战是供应商锁定。当您架构应用程序以依赖于在特定提供商平台上运行的外部函数时,以后可能很难迁移到不同的平台。

可能发生哪些类型的锁定?

对于构建为面向特定无服务器平台的应用程序,许多不同的因素可能会干扰干净地迁移到另一个提供商。这些可能来自无服务器实现本身,也可能来自应用程序设计中可能集成的提供商的相关服务的使用。

就实际无服务器实现引起的锁定而言,提供商之间最基本的差异之一可以是定义函数支持的语言。如果您的应用程序函数是用其他候选提供商不支持的语言编写的,则如果不使用受支持的语言重新实现逻辑,则迁移将是不可能的。无服务器不兼容性的一个更微妙的例子是不同提供商在平台内概念化和公开函数触发机制的方式上的差异。如果这些机制差异很大,您可能需要重新定义触发器在新平台上的实现方式。

当无服务器应用程序使用其提供商生态系统中的其他服务来支持其应用程序时,可能会发生其他类型的锁定。例如,由于无服务器函数不处理状态,因此通常使用提供商的对象存储产品来存储调用期间生成的任何工件。虽然对象存储使用标准接口广泛实现,但这表明了无服务器架构的约束如何导致更多地采用和依赖其他可用服务的生态系统。

开发人员为限制锁定所做的尝试

开发人员可以尝试一些方法来最大限度地减少应用程序锁定的可能性或影响。

用像 JavaScript 这样广泛支持的语言编写函数是避免硬依赖的最简单方法之一。如果您的选择语言受到许多提供商的支持,那么它会为您提供可能能够运行您的代码的其他平台的选择。

开发人员还可以尝试将其服务的使用限制在那些在每个平台上几乎相同地支持的商品产品上。例如,我们之前使用的对象存储示例实际上是一个理想的例子,说明一项服务很可能可以被另一家提供商的产品替代。您依赖的服务越专业化,就越难摆脱该生态系统。这是一个您必须根据具体情况评估的权衡,因为您可能不得不放弃专用工具,而选择更通用的替代品。

关于调试时缺乏控制和洞察力的担忧

评估无服务器以用于未来项目的开发人员对无服务器平台提供的缺乏控制和洞察力提出了常见的抱怨。部分原因是产品本身固有的,因为对运行代码的基础架构的控制必然会使该服务不属于无服务器类别。尽管如此,开发人员通常仍然担心在限制可见性和控制的环境中进行部署,尤其是在诊断可能影响正常运行时间和影响生产的问题时。

开发人员可以期望哪些类型的差异?

无服务器范式的承诺是将除代码本身之外的所有责任转移给平台提供商。这可以在运营开销和简化开发人员的执行环境方面产生许多优势,但它也使开发人员通常可能依赖的许多技术和工具更难以使用或无法使用。

例如,一些开发人员习惯于能够通过直接访问编程环境来调试,无论是通过使用 SSH 连接到主机还是通过内省代码并使用进程公开的数据。这些在无服务器环境中通常是不可能或不容易实现的,因为执行环境对用户是不透明的,并且只有特定的接口(如函数日志)可用于调试。这可能会使诊断问题变得困难,尤其是在无法在本地重现或在管道中调用多个函数时。

有哪些可用的帮助选项?

开发人员可以采取许多不同的策略来帮助他们在这种更受限制的调试环境中工作。

一些无服务器功能可以在本地运行或模拟,从而允许开发人员在自己的机器上调试他们无法在提供商的生产环境中调试的内容。许多工具旨在模拟常见的无服务器平台,以便开发人员可以重新获得他们可能缺少的一些诊断功能。它们可以让您单步执行函数、查看状态信息和设置断点。

对于在平台本身上进行调试,您必须尝试利用提供商提供的所有工具。这通常意味着在函数内部进行大量日志记录,使用 API 测试工具使用不同的输入自动触发函数,并使用平台提供的任何指标来尝试深入了解执行环境中可能发生的情况。

总结

无服务器环境在开发人员生产力、降低运营复杂性和实际成本节省方面提供了很多价值。但是,重要的是要意识到范式的局限性以及在设计在无服务器环境中运行的应用程序时可能必须解决的一些特殊挑战。

通过熟悉您可能面临的不同障碍,您可以更好地了解哪些应用程序可能从目前的权衡中获益最多。您还将更好地准备好通过额外的工具或设计考虑来解决这些问题,并更好地理解如何缓解或避免这些问题。

关于作者
Justin Ellingwood

Justin Ellingwood

自 2013 年以来,Justin 一直在撰写关于数据库、Linux、基础设施和开发人员工具的文章。他目前与妻子和两只兔子住在柏林。他通常不必以第三人称写作,这对所有相关方来说都是一种解脱。