Serverless体系结构是一种应用程序设计,它包含第三方“后端即服务”(BaaS)服务,和/或包含在“功能即服务”(FaaS)平台上的托管临时容器中运行的自定义代码。通过使用这些思想,以及类似于单页应用程序的相关思想,这样的体系结构消除了对传统的总是在服务器上的组件的大量需求。无服务器体系结构可以从显著降低的操作成本、复杂性和工程提前期中获益,但代价是增加对供应商依赖性和相对不成熟的支持服务的依赖。
Serverless计算,或者更简单地说,无服务器计算,是软件体系结构领域的一个热门话题。“三大”云供应商亚马逊、谷歌和微软都在无服务器领域投入了大量资金,我们看到了大量的书籍、开源项目、会议和软件供应商致力于这一主题。但是什么是无服务器的,为什么它值得考虑呢?
首先,我们来看看什么是Serverless(无服务器)。我们稍后将讨论该方法的优点和缺点。
Serverless是什么?
像软件的许多趋势一样,没有一个清晰的观点来解释什么是无服务器。首先,它包括两个不同但重叠的领域:
Serverless最初用于描述显著或完全结合第三方、云托管应用程序和服务的应用程序,以管理服务器端逻辑和状态。这些应用程序通常是“富客户端”应用程序,比如单页web应用程序,或者使用云可访问数据库(如Parse、Firebase)、身份验证服务(如Auth0、AWS Cognito)等庞大生态系统的移动应用程序。这些类型的服务以前被描述为“(Mobile)Backend as a Service”,我在本文的其余部分使用“ BaaS ”作为缩写。
Serverless也可以指服务器端逻辑仍然由应用程序开发人员编写的应用程序,但是,与传统体系结构不同,它运行在无状态计算容器中,这些容器是事件触发的、短暂的(可能只持续一次调用),并且完全由第三方管理。一种方式是“作为服务的功能”或“ FaaS ”。AWS Lambda是目前最流行的一个Functions-as-a-Service平台的实现,但是还有很多其他的实现。
在本文中,我们将主要关注 FaaS 。不仅是Serverless无服务器领域的更新和推动了大量的宣传,而且它与我们通常对技术架构的思考方式有很大的不同。
BAA和FAA在其操作属性(例如,无资源管理)上是相关的,并且经常一起使用。大型云供应商都有“无服务器产品组合”,包括BaaS和FaaS产品例如,这里是Amazon的无服务器产品页面。Google的Firebase BaaS数据库通过Google云函数为 Firebase 提供了明确的FaaS支持。
小型公司在这两个领域也有类似的联系。Auth0从实现用户管理的许多方面的BaaS产品开始,随后创建了FaaS服务Webtask。该公司在Extend上更进一步地采用了这一理念,这使得其他SaaS和BaaS公司能够轻松地将FaaS功能添加到现有产品中,从而创建统一的无服务器产品。
举几个例子
用户界面驱动的应用程序
让我们考虑一个传统的三层面向客户机的系统,带有服务器端逻辑。一个很好的例子是一个典型的电子商务应用程序我敢说一个在线宠物商店?
传统上,架构看起来像下图。假设它是在服务器端用Java或Javascript实现的,客户端是HTML+Javascript组件:
使用这种体系结构,客户机可能相对不智能,服务器应用程序实现了系统身份验证、页面导航、搜索和事务中的许多逻辑。
对于无服务器体系结构,最终可能会更像这样:
这是一个大大简化的视图,但即使在这里,我们也看到了一些重要的变化:
1. 我们已经删除了原始应用程序中的身份验证逻辑,并将其替换为第三方BaaS服务(例如 Auth0 )
2. 使用BaaS的另一个例子,我们允许客户机直接访问我们数据库的一个子集(用于产品列表),它本身完全由第三方(例如Google Firebase)托管。我们可能对以这种方式访问数据库的客户机具有与访问数据库的服务器资源不同的安全配置文件。
3. 前两点意味着非常重要的第三点:宠物商店服务器中的一些逻辑现在在客户机中—例如,跟踪用户会话,了解应用程序的UX结构,从数据库读取数据并将其转换为可用视图,等等。客户端正朝着成为单页应用程序的方向发展。
4. 我们可能希望在服务器中保留一些与用户体验相关的功能,例如,如果它是计算密集型的或需要访问大量数据。在我们的宠物商店中,一个例子是“搜索”。我们可以实现一个FaaS函数,通过API网关(稍后描述)响应HTTP请求,而不是像原始架构中那样始终运行服务器。客户机和服务器的“搜索”功能都从同一个数据库中读取产品数据。
5. 如果我们选择使用AWS Lambda作为FaaS平台,我们可以将搜索代码从原来的Pet Store服务器移植到新的Pet Store搜索函数,而无需完全重写,因为Lambda支持Java和Javascript,这是我们最初的实现语言。
最后,我们可以用另一个单独的FaaS函数替换“购买”功能,出于安全原因,我们选择将其保留在服务器端,而不是在客户端重新实现。它的前面也有一个API网关。在使用FaaS时,将不同的逻辑需求分解为单独部署的组件是一种非常常见的方法。
退一步讲,这个例子演示了关于无服务器架构的另一个非常重要的观点。在原始版本中,所有流、控制和安全都由中央服务器应用程序管理。在无服务器版本中,这些问题没有中央仲裁器。相反,我们更倾向于编排而不是编排,每个组件都扮演着更具体系结构意识的角色这一想法在微服务方法中也很常见。
这种方法有许多好处。正如Sam Newman在他的《构建微服务》一书中指出的那样,以这种方式构建的系统通常“更灵活,更易于更改”,无论是作为一个整体还是通过对组件的独立更新;有更好的关注点划分;还有一些引人入胜的成本效益,Gojko Adzic在这篇精彩的演讲中讨论了这一点。
当然,这样的设计是一种折衷:它需要更好的分布式监视(稍后将详细介绍),而且我们更依赖底层平台的安全功能。更重要的是,与我们最初使用的单片应用程序相比,有更多的移动部件可以让我们的大脑四处走动。灵活性和成本带来的好处是否值得多个后端组件增加的复杂性,这取决于上下文。
消息驱动的应用程序
另一个例子是后端数据处理服务。
假设您正在编写一个以用户为中心的应用程序,它需要快速响应UI请求,其次,它需要捕获正在发生的所有不同类型的用户活动,以便进行后续处理。想想一个在线广告系统:当用户点击一个广告时,你想很快地将他们重定向到该广告的目标。同时,你需要收集点击已经发生的事实,这样你就可以向广告客户收费。(这个例子并不是假设我在Intent Media的前团队正是有这个需要的,他们是以无服务器Serverless的方式实现的。