自从2014年AWS推出Lambda服务后,Serverless一词愈来愈热,已经成为一种新型的软件设计架构,即Serverless Architecture。做为一种原生于公共云的架构,Serverless有什么优缺点?是否能应用于传统企业程序?是否适合私有云场景?是否像不少文章宣称的同样,会成为将来改变云计算的中坚力量?做为一名云计算行业的老兵,做者想在此文中分享一些本身的观点。数据库
什么是Serverless小程序
Serverless并不神秘,用一个简单的例子就可讲明。咱们设计了一个AI应用,能够识别出图片中人物的人种,咱们把它做为一种SaaS服务架设在公共云上提供给客户使用,其典型的后端架构设计以下:后端
在该架构中,咱们购买的云主机上运行了Tomcat Web Server,用于承载Java编写的AI应用。用户经过API上传图片。受限于云主机的本地存储空间,为了知足大量客户同时上传图片,AI应用实现了一个存储网关将图片导入公共云的对象存储。图片导入完成后,AI应用从对象存储读入图片进行识别,并将结果存入公共云的数据库中(例如RDS),用户使用API查询结果。安全
AI应用上线一段时间后受到了用户的欢迎,愈来愈多的公司开始使用该服务。根据统计数据,大多数公司在上午9点~11点、下午2点~5点集中上传图片,为了知足该时间段的突发访问量,咱们设置了公共云的Auto-Scaling策略,在访问增长时动态建立更多的云主机来响应客户。AI应用的架构演化成:网络
在这个架构中,咱们须要作以下事情:数据结构
1. 管理云主机。咱们要关心CPU数量、内存大小、IP地址等等系统级的配置。同时还要关心云主机的操做系统,为部署AI应用拟定策略。操做系统和Tomcat的安全补丁也不能忽视,不然竞争对手可能雇佣黑客来攻击咱们的系统。架构
2. 配置公共云的Auto-Scaling的策略,应对高峰期突发访问量。并发
3. 使用公共云的对象存储和数据库。框架
4. 编写AI应用。less
要完成这些工做,咱们既要开发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就支持Java, Python和JVM系语言)编写AI应用,一切非核心业务都外包给了公共云营运商。
咱们的Serverless AI应用用到了两种技术。首先使用了公共云提供的对象存储和数据库服务,统称为BaaS(Backend as a Service,后端即服务)。其次用了Lambda框架,称为FaaS(Functions as a Service,函数即服务)。
使用BaaS和FaaS是Serverless应用的基本特征,符合这两个基本特征的应用可称为Serverless应用。
是BaaS,不是PaaS
AI应用用到了对象存储和数据库,未来或许还会用到消息队列。直观感受是在使用PaaS,为何还要造一个新词BaaS?技术圈有太多使人混淆的术语了。
BaaS并不是PaaS,它们的区别在于:PaaS须要参与应用的生命周期管理,BaaS则仅仅提供应用依赖的第三方服务。典型的PaaS平台须要提供手段让开发者部署和配置应用,例如自动将应用部署到Tomcat容器中,并管理应用的生命周期。BaaS不包含这些内容,BaaS只以API的方式提供应用依赖的后端服务,例如数据库和对象存储。BaaS能够是公共云服务商提供的,也能够是第三方厂商提供的,例如Facebook收购的Parse就是著名的MBaaS提供商(Mobile Backend as a Service)。从功能上讲,BaaS能够看做PaaS的一个子集,即提供第三方依赖组件的部分。
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被调用开始,到调用返回结束,不会有常驻内存的进程运行。此外公共云提供商还会限制代码执行的时间,超出时间后执行代码的进程会被强行销毁。例如AWS的Lambda可执行的最长时间为5分钟。
4. 代码必须作到完全无状态,两次调用间不能共享内存状态。咱们的AI应用最先使用了一个全局变量统计处理的图片数,每处理完一张图片该计数器就加一。使用FaaS后咱们不能再用任何全局变量或内存数据结构(例如Hashmap)在调用间共享数据,由于代码运行在独立的进程中,没法访问对方的内存地址空间。因而咱们对代码进行了改造,将全局计数器放到了公共云的Redis服务中,这为代码增长了额外的复杂性。
5. 水平扩展再也不是须要担忧的问题,FaaS会为每一个事件和请求运行一份新的代码。
6. 应用的部署方式从上传、配置整个程序变成上传一份打包代码的文件(例如Jar文件或一个Zip文件)。
Serverless为咱们带来了什么
对比传统架构,用Serverless架构改写的AI应用具备显著的优点。咱们再也不运维任何云主机和操做系统,甚至再也不运维Tomcat这样的Web容器,只须要专一于代码自己,全部配置、应用生命周期管理的工做都由FaaS框架负责。公共云的出现让咱们从物理硬件管理中解放出来,Serverless架构让咱们进一步从操做系统管理中解放出来,第一次真正专一于核心业务。
业务也变得更加敏捷了。咱们只须要编写核心业务相关的代码,例如AI应用中图像识别的部分。无需编写任何加载、部署、配置应用的代码,例如再也不须要配置systemd在系统启动时加载应用。
水平扩展也不是问题。正如前面反复说起的,FaaS框架会为每个事件、每个API请求都启动一份新的进程执行代码。这跟传统应用的线程池方式相似,每一个请求都在一个单独的线程中执行,区别在于线程之间共享同一内存地址空间,FaaS的进程间不共享任何内存。与线程池有最大线程数限制相似,FaaS框架一般也限制了最大进程数,例如AWS Lambda在一个Region默认能执行的最大并发调用是600,也就是说咱们的AI应用最多能在600个进程中同时执行。
最后,也是最重要的,Serverless架构为咱们节省了大量开支。咱们只需为AI应用运行的时间付钱,无需为应用等待请求的时间付钱。水平扩展的粒度从原来的云主机细化到进程,节省了额外的开支,不用再购买闲置的云主机来抵消Auto-Scaling的配置不精确带来的影响。业务的敏捷性提升也下降了营运成本,咱们再也不须要精通操做系统配置和管理的营运人员,不只节省了人力成本,也节省了应用从开发到上线的时间。
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 Microservices: Designing Fine-Grained Systems》)指导咱们如何作。但即便是他们,在面对Serverless架构时也会感到头痛,如何将业务拆分红成百上千个运行在独立进程、运行时间受限的函数是巨大的挑战。而是否须要如此细粒度的拆分是须要回答的第一个问题。有些问题或许变成无解难题又或成本极高,例如分布式数据库事务。
上面都是Serverless架构的一些固有局限,它们源于Serverless架构的特色,很难随着时间的推移、技术的完善而解决。除此以外,做为一个新的技术,Serverless还面临着集成测试困难、Vendor Lock-in、调试监控困难、版本控制等诸多不足,每一项都会成为采用Serverless架构的阻碍。
因为这些局限性,Serverless架构不会成为复杂应用的架构首选,相反,它应该是后端小程序的将来。
云端的应用有大量的小程序场景,例如识别一张图片、对一段音频/视频进行编解码、对IOT设备的请求返回一小段数据、将客户提交的工单经过邮件通知客服人员等等。这些基于事件触发的小程序在传统架构中实现起来是相对复杂的,你每每须要为20%的核心业务运营80%的支撑业务。Serverless完美的解决了这些问题,它能够成为复杂应用的一种补充架构。咱们能够将无状态的、事件触发的业务拆分红Serverless应用,让整个架构变得更加的简洁和高效。
Serverless也在不断演变,例如AWS最近引入的Step Functions就尝试解决调用间共享状态的问题,其效果有待观察。
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没有这个问题,水平扩展是架构自然自带的功能。
Serverless和微服务
Serverless和微服务没有直接关系,但二者有类似之处,例如都须要作业务拆分、强调无状态、具备敏捷特性等。Serverless在不少方面比微服务粒度更细,要求也更严格。例如微服务以服务为边界拆分业务,Serverless以函数为边界拆分业务;微服务能够有跨调用的内存状态共享,Serverless要求调用完全无状态。此外,Serverless依赖BaaS提供第三方依赖,而微服务能够自由选择第三方依赖来源,例如使用本地搭建的传统中间件栈(如本地MySql和消息总线)。
Serverless和容器
Serverless和容器是苹果和桔子的比较,不在一个平面上。Serverless是一种软件设计架构,容器是软件架构的承载者。虽然没有公开资料,但咱们能够推测相似于AWS Lambda这样的Serverless框架使用了某种程度的容器技术,否者难以实现语言无关和毫秒级的启动。尽管已经有一些开源项目使用Docker实现Serverless中的FaaS部分,笔者不认为AWS Lambda这样的公共Serverless框架直接使用了Docker,必定是一种更为轻量级、体积更小的容器技术,咱们或许能够将它称为Nano-Container。
Serverless对私有云有意义吗?
对于私有云来讲,如今将业务迁往Serverless架构还为时过早。首先Serverless是从公共云中演化出来的新型架构,适用于运行在公共云上的小程序。而私有云更多承载的是老而笨重的传统业务,难以用Serverless架构改造。其次Serverless依赖BaaS,在私有云中搭建和运维BaaS成本都不低,使用公共BaaS服务又受限于网络带宽和延时,容易致使系统不稳定。
随着企业应用的进一步云化、开源Serverless框架的成熟,私有云的Devops场景也能够采用Serverless做CI/CD,例如目前Jenkins承担的大部分工做均可以用Serverless替代,如用FaaS框架对应Jenkins自己,上传的代码对应Jenkins Job中的Bash脚本,将原来的Jenkins API触发Job改成触发FaaS中的代码。
总结
Serverless做为一种全新的架构,是云计算发展演化的必然结果。追求更细粒度的计费单元,更加专一于核心业务、将支撑业务外包给基础设施提供商是云计算的趋势。Serverless架构的特色,让编写事件触发的后端小程序变得更加容易。同时它也有自身内在的局限性,并不适合复杂的应用架构。从目前的状况看,部分采用Serverless的混合架构对公共云应用是个不错的选择,私有应用采用Serverless还为时过早。云计算技术正在飞速发展,将来还有无限可能。
转载自:http://blog.csdn.net/chenhaifeng2016/article/details/71425173
做者:张鑫