Serverless跟FaaS 看到的⼀篇关于FaaS介绍(典型代表,AWS的Lambda), 感觉很不错
⾃从2014年AWS推出Lambda服务后,Serverless⼀词越来越热,已经成为⼀种新型的软件设计架构,即Serverless Architecture。作为⼀种原⽣于公共云的架构,Serverless有什么优缺点?是否能应⽤于传统企业程序?是否适合私有云场景?是否像很多⽂章宣称的⼀样,会成为未来改变云计算的中坚⼒量?作为⼀名云计算⾏业的⽼兵,作者想在此⽂中分享⼀些⾃⼰的观点。
<a name="t0" target="_blank" ></a>什么是Serverless
Serverless并不神秘,⽤⼀个简单的例⼦就可讲明。我们设计了⼀个AI应⽤,可以识别出图⽚中⼈物的⼈种,我们把它作为⼀种SaaS服务架设在公共云上提供给客户使⽤,其典型的后端架构设计如下:
图⽚描述
在该架构中,我们购买的云主机上运⾏了Tomcat Web Server,⽤于承载Java编写的AI应⽤。⽤户通过API上传图⽚。受限于云主机的本地存储空间,为了满⾜⼤量客户同时上传图⽚,AI应⽤实现了⼀
个存储⽹关将图⽚导⼊公共云的对象存储。图⽚导⼊完成后,AI应⽤从对象存储读⼊图⽚进⾏识别,并将结果存⼊公共云的数据库中(例如RDS),⽤户使⽤API查询结果。
AI应⽤上线⼀段时间后受到了⽤户的欢迎,越来越多的公司开始使⽤该服务。根据统计数据,⼤多数公司在上午9点5点集中上传图⽚,为了满⾜该时间段的突发访问量,我们设置了公共云的Auto-Scaling策略,在访问增加时动态创建更多的云主机来响应客户。AI应⽤的架构演化成:11点、下午2点
图⽚描述
在这个架构中,我们需要做如下事情:
1. 管理云主机。我们要关⼼CPU数量、内存⼤⼩、IP地址等等系统级的配置。同时还要关⼼云主机的操作系统,为部署AI应⽤拟定策略。操作系
统和Tomcat的安全补丁也不能忽视,否则竞争对⼿可能雇佣⿊客来攻击我们的系统。
blower
2. 配置公共云的Auto-Scaling的策略,应对⾼峰期突发访问量。
3. 使⽤公共云的对象存储和数据库。
4. 编写AI应⽤。
要完成这些⼯作,我们既要开发AI应⽤,⼜要营运⽀撑业务(例如管理云主机⽣命周期、管理操作系统)。这是当前架构的现实:为20%的核⼼业务营运80%的⽀撑业务。
下⾯⽤Serverless架构改写AI应⽤:
图⽚描述
使⽤公共云提供的Serverless框架(例如AWS的Lambda)改写应⽤后,我们不再需要云主机和Tomcat了。⽤户也可以直接将图⽚上传到对象存储,AI应⽤注册了对象存储的⼀组事件,当图⽚上传完成后,代码会被触发运⾏在⼀个全新的进程内,对图像识别并将结果存⼊数据库。图⽚识别完后,AI应⽤退出,运⾏代码的进程也随之销毁。当有多个⽤户上传图⽚时,其架构变为:
图⽚描述
多个运⾏AI应⽤代码的进程被启动,并发处理⽤户上传的图⽚。
在Serverless架构的AI应⽤中,我们只需要做两件事情:
1. 使⽤公共云的对象存储和数据库。
2. ⽤公共云的Serverless框架编写AI应⽤。
与之前的架构相⽐,我们不再营运云主机、操作系统、Tomcat,同时也不需要配置Auto-Scaling Group,公共云的Serverless框架会在每个图⽚上传完成后启动⼀个进程运⾏AI应⽤,⾃动实现⽔平扩展。我们终于只需要关⼼核⼼业务了,⽤Serverless框架⽀持的语⾔(例如AWS Lambda就⽀持Javascript, Python和JVM系语⾔)编写AI应⽤,⼀切⾮核⼼业务都外包给了公共云营运商。英语在现翻译
我们的Serverless AI应⽤⽤到了两种技术。⾸先使⽤了公共云提供的对象存储和数据库服务,统称为BaaS(Backend as a Service,后端即服务)。其次⽤了Lambda框架,称为FaaS(Functions as a Service,函数即服务)。
使⽤BaaS和FaaS是Serverless应⽤的基本特征,符合这两个基本特征的应⽤可称为Serverless应⽤。
<a name="t1" target="_blank" ></a>是BaaS,不是PaaS
AI应⽤⽤到了对象存储和数据库,将来或许还会⽤到消息队列。直观感觉是在使⽤PaaS,为什么还要造⼀个新词BaaS?技术圈有太多令⼈混淆的术语了。
BaaS并⾮PaaS,它们的区别在于:PaaS需要参与应⽤的⽣命周期管理,BaaS则仅仅提供应⽤依赖的第三⽅服务。典型的PaaS平台需要提供⼿段让开发者部署和配置应⽤,例如⾃动将应⽤部署到Tomcat容器中,并管理应⽤的⽣命周期。BaaS不包含这些内容,BaaS只以API的⽅式提供应⽤依赖的后端服务,例如数据库和对象存储。BaaS可以是公共云服务商提供的,也可以是第三⽅⼚商提供的,例如Facebook收购的Par就是著名的MBaaS提供商(Mobile Backend as a Service)。从功能上讲,BaaS可以看作PaaS的⼀个⼦集,即提供第三⽅依赖组件的部分。
<a name="t2" target="_blank" ></a>FaaS是Serverless的核⼼
AI应⽤最初是⼀个典型Java程序,它可能使⽤Spring这样的技术,因为我们需要⼀个框架确保程序的各个组件能够被正确加载,需要MVC来保证REST API被正确的Controller处理。AI应⽤部署在Tomcat容器中,运⾏在云主机上,7 x 24⼩时运⾏,我们提供不间断的服务。在夜⾥12点到早晨8点,⼏乎没有⽤户使⽤,但我们还得让它待在那⾥,防⽌深夜偶尔使⽤的⽤户得到⼀个503错误⽽误会AI服务不稳定。我们为购买的云主机付钱,尽管⼀半的时间它的CPU使⽤率⼏乎为0,但没有公共云是按CPU
使⽤率计费的,不⼯作的时间也得付钱。我们必须关⼼Auto-Scaling Group的配置,如何准确的配置Auto-Scaling策略是⼀个技术活,需要长期的经验积累,在早期我们不得不多部署⼀些空闲的云主机以保证服务不会因Auto-Scaling的配置不当⽽拥塞。
⽤Serverless架构改写了AI应⽤后,这些痛苦就通通消失了。Spring框架和Tomcat去掉了,⽤Lambda的Java SDK,只需要实现⼀个Function Handler处理图⽚上传完成这个事件,这跟写⼀个Callback⼀样简单。在Function Handler中调⽤图⽚识别的相关逻辑,然后调⽤数据库的REST API存储结果。也不⽤构建MVC,不⽤配置Tomcat的XML⽂件,我们将存储⽹关这个功能完全去除掉了,因为⽤户可以直接上传图⽚到对象存储。
AI应⽤不⽤7 x 24⼩时运⾏了,没有⽤户上传图⽚时它只是⼀份编译好的代码。当⽤户图⽚上传完成时,FaaS会为AI应⽤启动⼀个新的进程执⾏代码。该进程在代码执⾏完成后⾃动销毁。我们只需为代码执⾏的这⼏⼗秒钟付钱,节省了很多开⽀。
最后我们⽆需操⼼Auto-Scaling的问题,FaaS会在需要的时候⾃动扩展。
这些就是FaaS的核⼼,从上⾯的例⼦⾥⾯可以归纳出它的特点:
1. FaaS运⾏的是后端代码⽽不是整个后端程序。例如AI应⽤仅仅包含处理图⽚上传完成这个事件的逻辑,并不是⼀个完整的后端程序,⽽是⼀段
后端代码。
2. 代码通过事件触发。由于不再有⼀个长期运⾏的进程等待或轮询⽤户请求,代码只能通过特殊的事件触发。这些事件由FaaS框架定义,例如上
传⽂件到对象存储、消息队列收到⼀条新的消息、API Gateway收到⼀个新的API请求等。
3. 代码的⽣命周期很短。例如我们的AI应⽤,从收到事件后Function Handler被调⽤开始,到调⽤返回结束,不会有常驻内存的进程运⾏。此
gamble
外公共云提供商还会限制代码执⾏的时间,超出时间后执⾏代码的进程会被强⾏销毁。例如AWS的Lambda可执⾏的最长时间为5分钟。
4. 代码必须做到彻底⽆状态,两次调⽤间不能共享内存状态。我们的AI应⽤最早使⽤了⼀个全局变量统计处理的图⽚数,每处理完⼀张图⽚该计
数器就加⼀。使⽤FaaS后我们不能再⽤任何全局变量或内存数据结构(例如Hashmap)在调⽤间共享数据,因为代码运⾏在独⽴的进程中,⽆法访问对⽅的内存地址空间。于是我们对代码进⾏了改造,将全局计数器放到了公共云的Redis服务中,这为代码增加了额外的复杂性。
5. ⽔平扩展不再是需要担⼼的问题,FaaS会为每个事件和请求运⾏⼀份新的代码。
6. 应⽤的部署⽅式从上传、配置整个程序变成上传⼀份打包代码的⽂件(例如Jar⽂件或⼀个Zip⽂件)。
<a name="t3" target="_blank" ></a>Serverless为我们带来了什么
对⽐传统架构,⽤Serverless架构改写的AI应⽤具有显著的优势。我们不再运维任何云主机和操作系统,甚⾄不再运维Tomcat这样的Web容器,只需要专注于代码本⾝,所有配置、应⽤⽣命周期管理的⼯作都由FaaS框架负责。公共云的出现让我们从物理硬件管理中解放出
来,Serverless架构让我们进⼀步从操作系统管理中解放出来,第⼀次真正专注于核⼼业务。
业务也变得更加敏捷了。我们只需要编写核⼼业务相关的代码,例如AI应⽤中图像识别的部分。⽆需编写任何加载、部署、配置应⽤的代码,例如不再需要配置systemd在系统启动时加载应⽤。
⽔平扩展也不是问题。正如前⾯反复提及的,FaaS框架会为每⼀个事件、每⼀个API请求都启动⼀份新的进程执⾏代码。这跟传统应⽤的线程池⽅式类似,每个请求都在⼀个单独的线程中执⾏,区别在于线程之间共享同⼀内存地址空间,FaaS的进程间不共享任何内存。与线程池有最⼤线程数限制类似,FaaS框架通常也限制了最⼤进程数,例如AWS Lambda在⼀个Region默认能执⾏的最⼤并发调
⽤是600,也就是说我们的AI应⽤最多能在600个进程中同时执⾏。
最后,也是最重要的,Serverless架构为我们节省了⼤量开⽀。我们只需为AI应⽤运⾏的时间付钱,⽆需为应⽤等待请求的时间付钱。⽔平扩展的粒度从原来的云主机细化到进程,节省了额外的开⽀,不⽤再购买闲置的云主机来抵消Auto-Scaling的配置不精确带来的影响。业务的敏捷性提⾼也降低了营运成本,我们不再需要精通操作系统配置和管理的营运⼈员,不仅节省了⼈⼒成本,也节省了应⽤从开发到上线的时间。
<a name="t4" target="_blank" ></a>Serverless不是银⼦弹,是后端⼩程序的未来
Serverless架构在某些应⽤场景的优势如此明显,有些⽀持者已经开始炒作它会成为颠覆性的云计算新架构了。技术圈向来如此,⼀些⼈总在孜孜不倦的寻找包治百病的灵药,和解决⼀切问题的银⼦弹。“All design is about tradeoff”,Serverless也不是银⼦弹,它有独特的优势,⽽这些优势也带来了不可避免的局限。
为每个事件/请求启动⼀个全新的进程运⾏代码是FaaS的核⼼,进程的启动延时是Serverless⾯临的第⼀个问题。取决于编写应⽤的语⾔,启动延时可以是10毫秒(如简单的Python应⽤),也可以是1分
钟(复杂的Java应⽤)。这样的延时对于realtime的程序是难以接受的。⽬前Serverless应⽤通常运⾏在公共云的多租户环境中,启动延时还受系统负载影响,很难保证应⽤在规定时间内被运⾏。公共云提供商⽬前没有对Serverless提供相应的SLA保证,笔者写这篇⽂章的时候,AWS Lambda还没有相关的SLA条款。
一般现在时的构成
Serverless⽆法⽤于⾼并发应⽤,为每个请求启动⼀个进程开销太⾼。例如双⼗⼀⽀付宝⾼峰期每秒处理的交易数为8.59万笔,如果使⽤Serverless架构,意味着我们的系统内每秒有8.59万个进程被创建⼜被销毁,这是难以负担的开销。
Serverless应⽤⽆法常驻内存,运⾏的时间是受限的。如果你的应⽤⽆法在数分钟内完成的⼯作,那Serverless不是你的选择,例如AWS Lambda给予进程的最长运⾏时间是5分钟,超时后进程将被强制终⽌。这对程序设计提出了挑战,例如我们的AI应⽤必须优化到在5分钟内完成复杂图像的识别。我们也不能编写执⾏长时间IO操作的应⽤,例如对对象存储中1T的数据进⾏复杂编码。
Serverless调⽤之间不能共享状态让编写复杂程序变得极度困难。⽆状态是互连⽹应⽤追求的⽬标,例如满⾜“12要素”的应⽤。但Serverless 将⽆状态进⾏的更加彻底,在不同的调⽤之间⽆法共享内存状态,例如使⽤hashmap。我们的AI应⽤中统计已处理图⽚总数的全局计数器在传统架构中只是⼀个全局变量,但在Serverless架构中它变成存储在内存数据库(Redis)中的⼀条记录,更新成本、保证
原⼦性等因素让我们的编码变得数倍复杂。对于⼤多云原⽣的互联⽹应⽤来说,这种彻底的⽆状态架构是⼀个巨⼤的挑战,⽽对于动辄有⼏⼗万、上百万⾏代码的、充满了状态的企业应⽤来说,Serverless的⽆状态改造⼏乎是⼀个⽆法完成的任务。
拦河坝
熟练的微服务的架构师,对将业务拆分成⼀个个单独的服务⾮常熟悉,也有不少的经典书籍(例如《Building Microrvices: Designing Fine-
Grained Systems》)指导我们如何做。但即使是他们,在⾯对Serverless架构时也会感到头痛,如何将业务拆分成成百上千个运⾏在独⽴进程、运⾏时间受限的函数是巨⼤的挑战。⽽是否需要如此细粒度的拆分是需要回答的第⼀个问题。有些问题或许变成⽆解难题⼜或成本极⾼,例如分布式数据库事务。
上⾯都是Serverless架构的⼀些固有局限,它们源于Serverless架构的特点,很难随着时间的推移、技术的完善⽽解决。除此之外,作为⼀个新的技术,Serverless还⾯临着集成测试困难、Vendor Lock-in、调试监控困难、版本控制等诸多不⾜,每⼀项都会成为采⽤Serverless架构的阻碍。
由于这些局限性,Serverless架构不会成为复杂应⽤的架构⾸选,相反,它应该是后端⼩程序的未来。
旧约
云端的应⽤有⼤量的⼩程序场景,例如识别⼀张图⽚、对⼀段⾳频/视频进⾏编解码、对IOT设备的请求返回⼀⼩段数据、将客户提交的⼯单通过邮件通知客服⼈员等等。这些基于事件触发的⼩程序在传统架构中实现起来是相对复杂的,你往往需要为20%的核⼼业务运营80%的⽀撑业务。Serverless完美的解决了这些问题,它可以成为复杂应⽤的⼀种补充架构。我们可以将⽆状态的、事件触发的业务拆分成Serverless应⽤,让整个架构变得更加的简洁和⾼效。
Serverless也在不断演变,例如AWS最近引⼊的Step Functions就尝试解决调⽤间共享状态的问题,其效果有待观察。
<a name="t5" target="_blank" ></a>Serverless不是传统的PaaS
Serverless跟PaaS之间的界线⽐较模糊,很多⼈认为Serverless是PaaS的⼀种,笔者也倾向于认为Serverless是特殊的PaaS形态。
Serverless由BaaS和FaaS两部分构成,BaaS负责提供业务的依赖服务,FaaS负责业务的部署和⽣命周期管理,从这个意义上来看,Serverless 的⾓⾊跟PaaS⼀样。与传统PaaS的区别在于,传统PaaS是以程序为粒度管理应⽤的⽣命周期,⽽Serverless是以函数粒度管理应⽤⽣命周期。传统PaaS中的
应⽤为常驻内存的进程,⽽Serverless应⽤运⾏完即销毁。此外,使⽤传统PaaS,⽤户仍需要关⼼⽔平扩展,例如如何配置Auto-Scaling Group,但Serverless没有这个问题,⽔平扩展是架构天然⾃带的功能。
<a name="t6" target="_blank" ></a>Serverless和微服务
提交英语>初中国旗下讲话稿
Serverless和微服务没有直接关系,但两者有相似之处,例如都需要做业务拆分、强调⽆状态、具有敏捷特性等。Serverless在很多⽅⾯⽐微服务粒度更细,要求也更严格。例如微服务以服务为边界拆分业务,Serverless以函数为边界拆分业务;微服务可以有跨调⽤的内存状态共
享,Serverless要求调⽤彻底⽆状态。此外,Serverless依赖BaaS提供第三⽅依赖,⽽微服务可以⾃由选择第三⽅依赖来源,例如使⽤本地搭建的传统中间件栈(如本地MySql和消息总线)。新东方学校
<a name="t7" target="_blank" ></a>Serverless和容器
Serverless和容器是苹果和桔⼦的⽐较,不在⼀个平⾯上。Serverless是⼀种软件设计架构,容器是软
件架构的承载者。虽然没有公开资料,但我们可以推测类似于AWS Lambda这样的Serverless框架使⽤了某种程度的容器技术,否者难以实现语⾔⽆关和毫秒级的启动。尽管已经有⼀些开源项⽬使⽤Docker实现Serverless中的FaaS部分,笔者不认为AWS Lambda这样的公共Serverless框架直接使⽤了Docker,⼀定是⼀种更为轻量级、体积更⼩的容器技术,我们或许可以将它称为Nano-Container。
<a name="t8" target="_blank" ></a>Serverless对私有云有意义吗?
对于私有云来说,现在将业务迁往Serverless架构还为时过早。⾸先Serverless是从公共云中演化出来的新型架构,适⽤于运⾏在公共云上的⼩程序。⽽私有云更多承载的是⽼⽽笨重的传统业务,难以⽤Serverless架构改造。其次Serverless依赖BaaS,在私有云中搭建和运维BaaS成本都不低,使⽤公共BaaS服务⼜受限于⽹络带宽和延时,容易导致系统不稳定。
随着企业应⽤的进⼀步云化、开源Serverless框架的成熟,私有云的Devops场景也可以采⽤Serverless作CI/CD,例如⽬前Jenkins承担的⼤部
>美国高二留学