Serverless架构综述

本文讲的是Serverless架构综述【编者的话】Serverless是当今软件架构领域最热的话题,关于这个话题,我们有很多介绍,设置举办过展会。但是什么是Serverless,为什么会成为热点,通过这篇文章,希望能启发大家的思考。

作者简介:Mike Roberts, 是NYC的一个工程师领导者。除了领导团队之外,他还花大量时间进行开发,特别是Clojure,对软件架构比较有研究。他认为Serverless架构应该会是未来的一个新趋势。

我们仍然先从什么是Serverless开始,我会从中立的角度讨论这种架构的优缺点。

什么是Serverless?

跟很多其它软件类似,对Serverless还没有清晰定义,但是肯定有两个互相有重叠的定义:
  1. Serverless最初是用于描述依赖第三方服务(‘云端’)实现对逻辑和状态进行管理的应用。典型的包括“厚客户端”(例如单页Web应用、移动应用),他们一般都使用基于云端的数据库(例如Parse、Firebase),认证服务(Auth0、AWS congnito)等。这类服务以前被称为”(Mobile) backend as a Service ”,我将在本文中称他们为“BaaS”。
  2. Serverless也可以指这样的应用,一部分服务逻辑由应用实现,但是跟传统架构不同在于,他们运行于无状态的容器中,可以由事件触发,短暂的,完全被第三方管理。(感谢ThoughtWorks在最近Tech Radar中做出的定义)。这种思路是‘Functions as a Service / FaaS’,AWS Lambda是目前最佳的FaaS实现之一,本文后续介绍中将使用FaaS作为这种架构的缩写。

但是我更愿意讨论的是本领域第二种方式,相比来说技术架构更新,引领了Serverless的很多创新。

然而,这两个领域开始融合,一个例子是Auth0,一开始Auth0是作为Baas(‘Authentication as a Service’),但是随着Auth0 webtask的发布,演变成了FaaS应用。

更多场合,当开发基于BaaS的应用时,特别当开发基于web的应用而不是移动应用时,更需要一部分服务端功能。特别当跟正在使用的BaaS整合在一起时,FaaS模式可以作为最佳实践。这类功能包括数据认可(以免客户端恶意攻击)和计算敏感进程(例如图像或者视频篡改)。

例子

UI驱动应用

先讨论一个带有服务功能逻辑的传统面向客户端的三层应用,一个典型的电子商务应用(例如在线宠物商店)。

一般架构如图所示,假如服务端用Java开发完成,客户端用HTML/Javascript:
Serverless架构综述

这种架构中,因为有不少系统逻辑,例如认证、页面导航、搜索、交易等在服务端完成,客户端显得相对不太智能。

采用Serverless架构,开起来如图二所示:
Serverless架构综述

这仅是最简单的视图,但是即使如此,还是有不少改变。请注意并不是建议架构迁移,而是使用这个工具来解释某些Serverless概念。
  1. 删除了认证逻辑,而用第三方BaaS服务取代。
  2. 使用另外一个BaaS,允许客户端直接访问架构与第三方(例如AWS Dynamo)上的数据子库。通过这种方式提供给客户更安全的访问数据库模式。
  3. 前两点中包含着很重要的第三点,也就是以前运行在宠物商店服务端的逻辑现在都转移到客户端中,例如跟踪用户访问,理解应用的UX架构(例如页面导航),读取数据库转化为可视视图等。客户端则慢慢转化为单页面应用。
  4. 某些我们想保留在服务端的UX相关功能,例如,计算敏感或者需要访问大量数据,比如搜索这类应用。对于搜索这类需求,我们不需要运行一个专用服务,而是通过FaaS模块,通过API Gateway对http访问提供响应。 这样可以使得客户端和服务端都从同一个数据库读取相关数据。 由于原始服务使用Java开发,AWS Lambda(FaaS提供者)支持Java功能,因此可以直接从宠物商店服务端将代码直接移植到宠物商店搜索功能,而不用重写代码。
  5. 最后,可以将‘purchase’功能用另外一个FaaS功能取代,因为安全原因放在服务端而不是重新在客户端重新实现,当然前端还是APIGateway。

消息驱动应用

一个不同的例子是后台数据处理服务。例如正在写一个面向用户的应用,需要对UI请求快速响应,但是同时还想获取所有发生的行为。我们设想一个在线广告系统,当用户点击一个广告时,希望快速导向目标,但是同时,需要搜集点击量以便向广告商收取费用。

传统的架构,‘Ad Server’同步地响应客户,但是同时还会向异步处理‘点击量’的应用发送一个消息更新,以便以后向广告商收费的数据库。
Serverless架构综述

而Serverless架构则如下:
Serverless架构综述

架构跟我们第一个例子有些许不同,这里我们用FaaS功能取代了一个一直运行的应用。此FaaS运行于方案提供商提供的消息驱动上下文之间。需要注意的是供应商提供了消息代理和FaaS,两者之间更加紧密地合作在一起。

FaaS环境通过复制出若干实例也可以并行处理这些点击,这对开发无疑带来全新概念。

解密 ‘Function as a Service’

我们已经多次提过FaaS概念,现在我们来看看其真正含义。我们先看看Amazon Lambda产品的公开说明。我自己添加了标记,将会逐一展开说明。

AWS Lambda使得用户不需部署或者管理服务就可运行代码(1)…通过Lambda,可以虚拟化地运行任何类型应用和后台服务(2)—都是免管理的。只需上载代码,Lambda会管理其他一切(3)并且以高可用模式扩展应用(4)可以配置自动从其他AWS服务激活代码(5)或者从任何移动应用中调用(6)。
  1. 功能上FaaS就是不需要关心后台服务器或者应用服务,只需关心自己的代码即可。与现代其他架构相比(例如容器和PaaS),这是最大的不同。 如果回到上面所说的点击案例,FaaS代替了点击处理服务器(至少是一台物理服务器,但是绝对是一个特定应用),因为这种架构不需要一台指定服务器,甚至不需要一个一直运行的应用模块来处理。
  2. FaaS并不需要特定框架或者库,从编程语言和环境角度更像是一个普通应用。例如AWS Lambda功能可以采用JavaScript、Python和任何其他JVM语言(Java、Clojure、Scala等)。Lambda功能可以运行任何其他绑定部署的代码,因此可以用任何可以编译成Unix进程的语言。FaaS功能也有一些架构上的限制,特别当面对状态(state)或者执行区间(execution duration)的问题,后面我们会提到。回到上面说的点击系统,转到FaaS架构唯一需要更改的代码就是‘main method/startup’代码(示例中被删除了),开始来代码应该是在顶层消息处理器中(‘message listener interface’实现),但却可能只是在方法签名(method signature)的一个小小改变。所有其他代码(例如写入数据库的代码)都没有任何改变。
  3. 因为没有应用服务需要部署因此FaaS跟传统架构差别很大,只需要上载代码到FaaS提供者就足够了。现在这也就意味着上载一个代(例如以zip或者JAR形式),然后调用特定API初始话此更新。
  4. 水平扩展是完全自动、弹性,由提供者来管理。如果应用需要并发处理100个请求,提供者将会处理后台所有需求。‘计算容器’只是短暂运行应用代码,运行完毕后就销毁这些需求。仍然回到点击案例,假如今天运气不错,客户点击了日常点击量的十倍。点击进程能处理这些变化吗?例如,我们设计的代码可以同时处理多条消息吗?即使可以,一个进程可以处理这么多负载吗?是否可以动态自动扩展进程还是需要手工重新配置?有了FaaS,代码只需要处理并发,而其他自扩展功能则由提供者自动处理。
  5. FaaS功能是由提供者定义的消息类型触发的。对于Amazon AWS,这些出发包括 S3(文件)更新,时间(调度任务)和添加到消息总线上的消息(例如kinesis)。代码一般都会提供消息源所需的参数。点击案例中,已经假定我们使用了支持FaaS的消息代理。如果还没有的话,就需要一个,对消息生产者也有同样的要求。
  6. 许多提供者允许FaaS功能作为http响应来出发,一般是API网关。例如在宠物商店案例中,‘search’和‘purchase’功能。

State状态

FaaS功能如果使用本地状态,会有很多严格限制。简单说需要假设任何进程间或者主机状态对子进程都不可见,包括在RAM和写到本地盘上的状态。换句话说,从一个部署单元来看FaaS功能是无状态的。这一点对应用架构来说影响很大,同样‘Twelve-Factor App’概念对架构也有细致的限制。

考虑到限制,应该如何解决呢?一般来说FaaS功能要么是自然无状态,也就是提供纯功能调用,要么会使用数据库,跨进程见cache(例如Redis),或者共享文件系统(或者S3)来存放状态或者提供处理请求所需的更多输入信息。

Execution Duration执行区间

FaaS功能一般会限制每个功能允许运行多长。目前AWS Lambda功能允许最多运行5分钟,如果超出就被强行退出。这意味着某些长时间运行的任务如果转到FaaS架构,就需要重新设计,也就是说需要多创建几个不同FaaS功能协调器,而在传统架构中,只需有一个就可以了。

Startup Latency启动延迟

目前FaaS功能多长时间会响应跟很多因素有关,其延迟可能从10ms到2分钟。听起来不太好,我们用AWS Lambda举个例子。

加入你的功能用Javascript或者Python开发,也不大(例如小于几千行代码),此时延迟一般不会超过10-100ms。更大的功能有可能会有更长的响应时间。

如果Lambda功能运行在JVM上,当JVM运行时,偶尔会看到响应时间更长(例如大于10秒)的情况,然而对于以下情况,高延迟则会很显著:
  • 应用并不是很活跃,大概每十分种处理一次事件
  • 突然流量爆发。例如从每秒10次濡染增长到每秒100次。

前者一般可以通过提高响应频次的方法来解决。

这些问题需要考虑吗?的确需要看应用的具体情况。我以前团队用Java开发过一个异步消息处理Lambda应用,每天处理上亿条消息,而且没有启动延迟问题。也就是说不管采用什么开发语言,如果你想写一个低延时交易应用,现在可能并不适合采用FaaS架构。

为了确认应用是否有问题,最好是用生产类型负载测试一下。如果场景不适合,可以考虑转向FaaS提供商。

API Gateway

Serverless架构综述

关于FaaS我们之前讨论过‘API Gateway’,一个API Gateway是一个http服务器,路由和服务点都在配置里定义,每个路由都跟一个FaaS功能有联系。当一个API Gateway接受请求,找到提供请求服务的路径,然后调用相关FaaS功能。一般API Gateway允许将http参数映射成FaaS功能需要的输入参数。API Gateway将FaaS功能结果转换为http响应,返回调用者。

Amazon Web Services等云服务提供商都各自提供自己的API Gateway。
除了API Gateway路由请求需要认证,输入验证,相应代码映射等,有时候可能还会想是否这是个好主意,那么让我们更深入论证一下。

APIGateway+FaaS的一个应用场景就是用Serverless方式创建http前端微服务,充分利用扩展,管理和其它与FaaS功能有关的其它优点。

目前API Gateway开发工具并不太成熟,因此定义API Gateway应用时候最好不是非常核心的引用。

Tooling工具

API Gateway工具不太成熟事实上也同样适用于Serverless FaaS。然而有些例外,例如Auth0 Webtask将大量重要UX开发放在自己的工具上。Tomasz Janczuk在最近的Serverless会议上给出了很好的演示。

排错和监控对于Serverless应用有点儿需要技巧。我们后续会谈到它们。

Open Source开源

Serverless FaaS目前最大优势就是产品安装部署透明,因此开源对这块的影响并不是像对其它领域,例如Docker和容器。未来有可能出现FaaS/API Gateway平台会运行在云或者工作站上。IBM的OpenWhisk是这样一种实现,看这样的平台如何演变也是很有意思的事情。

除了运行部署,其它开源工具和框架用于定义,部署和运行时支持,例如Serverless Framework跟API Gateway+Lambda结合比AWS更早。尽管很依靠Javascript,但是如果你写JS API Gateway应用,绝对值得一试。

另外一个例子是Apex,一个用于简化AWS Lambda功能安装,部署和管理的工具。Apex很有趣的一个地方在于可以选用Amazon并不直接支持的语言(例如Go)来开发Lambda功能。

什么不是Serverless?(What isn’t Serverless?)

目前我们定义Serverl主要意味着'Backend as a Service' 和 'Functions as a Service'。针对他们我们也深入探讨了各种因素。

开始讨论有缺点之前,我们再来看看定义,或者至少定义一下什么不是‘Serverless’。很多人会很迷惘,因此讨论一下还是很值得的。

跟PaaS比较(Comparison with PaaS)

考虑到Serverless FaaS功能很像12-Factor applications(译者注:是一种创建现代,可扩展,可维护SaaS应用的方法论),它们只是像Heroku的另外一种PaaS吗?下面引用Adrian Cockcroft的一段论述:

如果你的PaaS可以将以前半秒启动的应用在20ms内启动,就叫它Serverless。——Adrian Cockcroft
换句话说,许多PaaS应用不会每次请求来了启动,请求结束则关闭。而FaaS平台是这样的。

好吧,然并卵。如果我是一个很好地12-Factor App开发者,并不会太多开发上的不同吧?这是真的。但是在运维应用上却又很大不同。因为所有好的DevOps-savvy工程师都会同时考虑开发和运维,对吧?FaaS和PaaS在运维方面最大不同来自于可扩展性(scaling)。许多PaaS架构,用户必须考虑scale,例如杜宇Heroku来说需要运行多少Dynos;而对于FaaS应用来说,这是完全透明的。即使配置PaaS应用自扩展,也不会将它设置为请求级别的(除非负载访问情况很特殊),而对FaaS应用来说,从投入角度更加有效。

考虑到这些优势,为什么还是用PaaS架构?有一些原因,但是工具,API Gateway成熟度应该是最大原因。另外,12-Factor Apps为了优化,实现PaaS时会采用App内部只读cache,而对于FaaS来说则没有这个选项。

#NoOps

Serverless并不意味着‘免维护’。或许根据你对Serverless有多适应,应该意味着‘不需定时维护’,有很重要的两点需要考虑。

首先,‘Ops’意味着比服务器维护更多的内容。至少还包括监控,部署,安全,网络,以及产品排错和系统扩展。这些问题对于Serverless应用来说仍然还在,需要一种策略来处理。某种程度上,在Serverless世界Ops有些困难,因为一切都是新的。

第二,即使系统管理还在发生,其实我们是他们外包给了Serverless。这并不是件坏事,我们实际上外包了很多事情。但是根据你真正想做什么,可能是件好事也可能时间坏事,有时候这种抽象会出现问题,你需要确认到底是谁在支持你的应用。

Charity Majors在最近的Serverless会议上发言讨论了这一论题,建议大家上网去读读。

Stored Procedures as a Service

关于Serverless FaaS另外一个论点在于‘Stored Precedures as a Service’,我认为这一论点来自于很多FaaS的实现(包括本文中用到的例子)都是小段代码访问数据库。如果这就是所有要求,用FaaS当然是可以的。但是因为这仅仅是FaaS的一小部分功能,用这种想法考虑FaaS是以偏概全了。

还有人说,考虑FaaS是否会带来跟stored procedures同样的问题是值得的,包括技术方面的问题(Camile在tweet上提到这些问题)。使用stored procs值得审视FaaS上下文,这里有很多教训。例如:
  1. 经常需要用特定语言,或者是特定的框架、某种语言的扩展。
  2. 因为执行时必须要有数据库上下文,测试很困难。
  3. 版本控制需要技巧

注意,以上所述并不能涵盖所有stored procs,但是确实是我实际中遇到的问题。我们看看是否也适用于FaaS:
  1. 第一点对FaaS实施绝对不使用,因此可以毫不犹豫将它划去。
  2. 因为这里我们只讨论编码。整合测试是我们需要后续讨论的另外一个问题。
  3. 应为FaaS功能对于代码版本控制足够了,但是对于应用打包来说并没有成熟模板。Serverless框架自己提供了一套,AWS也宣称在2016年五月Serverless大会上发布一套,但是至少现在是一个值得担心的问题。

原文地址:Serverless Architectures(翻译:杨峰)

原文发布时间为:2016-06-24

本文作者:杨峰

本文来自云栖社区合作伙伴Dockerone.io,了解相关信息可以关注Dockerone.io。

原文标题:Serverless架构综述

上一篇:机器学习中的贝叶斯方法---先验概率、似然函数、后验概率的理解及如何使用贝叶斯进行模型预测(1)


下一篇:正在考虑微服务架构的松耦合?小心这些陷阱!