分享到

简介

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

尽管无服务器计算有许多优点,但它也有一些必须承认或解决的挑战才能成功。在本指南中,我们将讨论当前一代解决方案的一些主要痛点,并讨论它们的含义以及如何解决它们。您将更好地了解可能需要满足哪些要求以及可能遇到的障碍。

冷启动问题

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

什么是冷启动问题?

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

缺点是,当资源完全关闭时,下次需要执行时会出现可预测的延迟。需要重新分配资源来运行函数,这需要时间。对于最近使用过的“热”函数,您会得到一组性能特征;对于需要等待平台创建执行环境的“冷”函数,您会得到另一组性能特征。

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

开发人员和平台已经尝试了多种方法来解决这个问题。一些开发人员会安排“虚拟”请求,以使与其函数关联的资源保持待机状态。许多平台在其服务中添加了一个额外的层,允许开发人员自动保持资源处于待机状态。

这些解决方案开始模糊无服务器环境的定义界限。当开发人员在代码未主动执行时被迫为待机资源付费时,这引发了对无服务器范式某些基本主张的质疑。

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

应用程序设计限制

无服务器模型的一个基本挑战是它所施加的应用程序设计限制。无服务器平台仅适用于能在其限制内工作的应用程序。其中一些是云计算固有的,而另一些要求则是由无服务器模型特别规定的。

设计一个云友好的架构

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

这意味着您的应用程序必须部分设计成由无服务器提供商执行的一系列函数。您必须对在您无法控制的基础设施上进行的处理感到满意。此外,您必须能够将应用程序的功能分解为可以远程执行的离散函数。

处理无状态执行

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

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

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

供应商锁定问题

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

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

对于针对特定无服务器平台构建的应用程序,许多不同的因素可能会妨碍干净地迁移到其他提供商。这些因素可能源于无服务器实现本身,也可能源于使用可能集成到应用程序设计中的提供商相关服务。

就实际的无服务器实现造成的锁定而言,提供商之间最基本的差异之一可以是支持的函数定义语言。如果您的应用程序函数是用其他候选提供商不支持的语言编写的,那么在不使用受支持的语言重新实现逻辑的情况下,迁移将是不可能的。一个更微妙的无服务器不兼容性示例是不同提供商在概念化和暴露平台内函数的触发机制方面存在的差异。如果这些机制显著不同,您可能需要重新定义在您的新平台上如何实现触发器。

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

开发人员如何尝试限制锁定

开发人员可以通过一些方法来尽量减少其应用程序被锁定的可能性或影响。

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

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

调试时缺乏控制和洞察力的问题

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

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

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

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

有哪些可选方案可以提供帮助?

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

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

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

总结

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

通过熟悉您可能面临的不同障碍,您可以更好地做出明智的决定,了解哪些应用程序最能从现有权衡中受益。您还将更好地准备好解决这些问题,并更好地了解如何通过额外的工具或设计考虑来缓解或避免它们。

作者简介
Justin Ellingwood

Justin Ellingwood

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