无服务器

2016年6月20日

无服务器架构是基于互联网的系统,其中应用程序开发不使用传统的服务器进程。相反,它们完全依赖于第三方服务的组合、客户端逻辑和服务托管的远程过程调用 (FaaS).

无服务器应用程序通常会大量使用第三方服务来完成传统上由服务器处理的任务。这些服务可能是相互操作的丰富服务生态系统,例如 亚马逊 AWSAzure,或者它们可能是试图提供交钥匙功能集的单个服务,例如 ParseFirebase。这些服务提供的抽象可能是基础设施的(例如消息队列、数据库、边缘缓存…)或更高层次的(联合身份、角色和能力管理、搜索…)。

基于通用服务器的 Web 应用程序的主要职责之一是控制请求-响应周期。服务器端的控制器处理输入,调用适当的应用程序行为并构建动态响应,通常使用模板引擎。在无服务器应用程序中,应用程序行为从第三方服务中编织在一起,客户端控制流和动态内容生成取代了服务器端控制器。丰富的 JavaScript 应用程序、移动应用程序(以及越来越多的电视或嵌入式物联网应用程序)通过进行 API 调用并使用客户端 UI 框架生成动态内容来协调不同服务之间的交互。

基于服务器的 Web 应用程序最实质性的部分是控制器和基础设施之间发生的处理;业务逻辑。一个长期运行的服务器托管实现此逻辑的代码,并在应用程序保持活动状态的整个时间内执行所需的处理。在无服务器应用程序中,自定义代码组件的生存周期要短得多,更接近于单个 HTTP 请求/响应周期的时序。代码在请求到达时激活,处理请求,并在活动结束后进入休眠状态。此代码通常存在于托管环境中,例如 Amazon LambdaAzure FunctionGoogle Cloud Functions,这些环境负责代码的生存周期管理和扩展。(这种组织软件的方式有时被称为 “函数即服务” - FaaS。)每次请求的短生存周期也适合每次请求的定价模型,这使得一些团队能够显著节省成本。 [1]

一种新的风格,一套新的权衡

所有设计都是关于权衡的。以这种风格构建的应用程序有一些明显的优势,当然也有一些问题。

最常被断言的优势是成本。在具有突发流量模式的系统中,为了适应突发流量,让一个强大的服务器在大多数时间处于冷运行状态既浪费又昂贵。基于云的基础设施服务的按需定价模型可以为必须处理这种流量的团队提供显著的成本降低。此外,在传统的基于服务器的应用程序中,应用程序及其所有相关基础设施组件的可扩展性是开发团队的责任。这通常比使用在 URL 上提供的 API 的简单抽象之后透明扩展的服务更难。因此,团队经常发现无服务器应用程序可以更容易地扩展

另一方面,也有一些新的成本。将单个应用程序拆分为由服务编织而成的某种东西的概念开销是巨大的,并且随着使用服务的数量和种类而增加。当应用程序的很大一部分在外部服务中实现和运行时,本地开发和单元测试也更加困难。团队通常使用 广义堆栈测试语义监控 来在一定程度上抵消这种影响。

最后,无服务器系统被认为更容易操作和维护。第三方服务在安全性、可用性、可扩展性和性能方面投入了大量资源。这些事情通常需要专门的技能,可能不在较小的开发团队的专业领域内。但这并不意味着团队可以忘记运营。开发团队仍然需要处理服务中断、停机、停用和减速带来的问题,并防止这些问题对他们自己的应用程序产生级联影响。

进一步阅读

Mike Roberts 正在撰写一篇关于无服务器架构的更详细的文章,其中包括示例、关于权衡的更多细节以及与类似风格的对比。

Patrick Debois 在他从 serverlessconf 2016 中的演讲中更多地谈论了无服务器架构的运营现实。

致谢

我要感谢 Martin Fowler 在插图、编辑建议和本文的指导方面提供的帮助。此外,还要感谢 Mike Roberts、Paul Hammant 和 Ken McCormack 的投入,以及 Chris Turner、Ian Carvell、Patrick Debois 和 Jay Sandhaus 抽出时间讨论他们构建无服务器应用程序的经验。Jean-Noël Rouvignac 指出了我的一些错别字。

注释

1: 其他自动化服务,例如 ZapierIFTTT 似乎在精神上预示着,如果不是在开发人员友好性方面,那么 AWS Lambda、Azure Function 或 Google Cloud Functions 可以做的事情。