Serverless 话题涉及范围极广,几乎包含了代码管理、测试、发布、运维和扩容等与应用生命周期关联的全部环节。AWS Lambda 是 Serverless 领域的标志性产品,但若是将其应用于核心业务,可能会遇到如下难题:(仅表明做者我的观点)首度揭秘: java
本文将介绍阿里云中间件团队在探索 Serverless 过程当中的思考以及正在作的事,目的是尽量让开发者少改代码,甚至不改代码,就能具有 AWS Lambda 的技术优点。
Cloud Service Engine 云服务引擎(如下简称CSE),是阿里云中间件团队开发的面向通用 Serverless 计算的中间件产品,目的是具有 AWS Lambda 的各类优点,同时能够解决用户在使用 AWS Lambda 时遇到的难题。web
AWS 对 Serverless 定义是:(摘自 AWS 官网)spring
AWS 无服务器平台提供的功能:(摘自 AWS 官网)服务器
AWS 的整套 Serverless 方案很是完善,可是没有解决存量应用如何迁移到 Serverless 架构的问题。仅仅是针对新开发的应用,建议用户使用 FaaS 方式开发,才有机会转向 Serverless 架构。笔者认为,要将 Serverless 架构大规模推广,必需要能有针对存量业务的解决方案。网络
云计算,归根结底是一种 IT 服务提供模式,不管是公共云仍是专有云(以IT设备的归属不一样分类),其本质都是帮助 IT 的最终使用者随时随地,而且简便快速地,获取 IT 服务,目前,IaaS、PaaS都已经作到了按需付费,PaaS 甚至作到了按请求付费,如DB,CACHE,MQ等,可是 IaaS 的付费粒度仍然是时间维度,最快按照小时付费,以分钟来交付。
所以,当下的云计算场景,应用的开发维护方式相比传统 IDC 时代的开发维护,差异还不是很大。但 AWS Lambda 提供了一种全新的开发维护方式,用户只须要写好业务代码,提交到云上,全部和机器容量、可用性、机器为单位的运维工做能够所有交给了云平台,这种模式极大的释放了云的弹性价值,真正作到了按需付费。
CSE 试图提供一种更规模化的解决方案,像 AWS Lambda 同样,能进一步释放云的弹性价值,而且能够平滑迁移存量应用。数据结构
存量在线应用程序具备如下特色架构
基于以上客观条件,一般作法是提早预约好机器数量来应对任意时刻的流量峰值,假设上述技术参数变为毫秒级,就有机会将应用程序架构演变成下图所示方式。app
上图中,Service A 在调用 Service B 时,若是 B 的容量充足,则调用成功;若是 B 的容量不足,这时候若是线程池满,则直接触发限流阀值,A 会收到一个错误码,而后直接调用资源总控系统,资源总控系统负责新分配一个 Service B 实例,这个分配的速度很是快,耗时几十毫秒,同时把 B 的服务地址直接返回给 A,A 会将以前未完成的请求发送到新建立的 Service B。
以上过程对于开发者彻底透明,具有了如下价值:框架
价值三:按照请求计费;由于每一个实例的启动时间甚至比 FaaS 的函数启动时间还快,就能够像 FaaS 同样来核算成本,成本只与如下因素有关less
综上所述:为了作到以上描述的分布式架构,关键技术点在于应用启动速度,这里的应用启动速度是指应用能够正常处理流量为止。
应用在启动过程当中一般会初始化多个组件,如各类中间件、数据结构,以及网络调用外部服务。在阿里内部普遍使用 SOA 和微服务的状况下,应用在启动过程当中会大量加载共享业务 SDK,存在启动过程达到10分钟量级的状况,个别应用可能会更长。所以,这个启动过程必须提早完成,才有机会以“临阵磨枪”的方式去建立新实例。
L1 弹性能力是指在一台物理机或者大规格的 ECS 上部署同一个应用的多个实例,经过操做系统和 JVM 的优化,一个占用 4G 内存的应用,即便部署10份,仅需占用2.2G RAM。
L1 总结来看是一种高密度部署方式,因为应用已经提早启动,而且对容器进行冻结,意味着这个应用实例 CPU 占用率为0,RAM 占用至关于以前的1/20,可是具有了毫秒级弹性的能力。L1的特色是启动速度极快,可是须要消耗资源,且只能垂直弹性。
L2 是经过将应用程序启动后在 RAM 中的指令和数据结构 dump 到磁盘文件,只须要在机器之间拷贝文件便可以达到横向弹性的能力,这个时间消耗主要是数据的网络传输时间+内存拷贝时间,大约在5秒左右就能够完成。L2 的成本开销只有网络磁盘容量,开销极低,可忽略不计。
L2 的每一个 SNAOSHOT 对应一个可运行的实例,例如预计一个应用须要最大启动100个实例,那么须要提早生成100个 SNAOSHOT,每一个 SNAOSHOT 对应一个运行实例,须要启动时,从远程磁盘加载这个 SNAPSHOT。
此方案经过 L1 和 L2 的组合来达到加速应用启动的目的,在支持必定流量脉冲能力下,能够最大50ms内启动任意应用,平均在10ms内完成。
L1 采用经过 fork 种子进程达到快速启动的效果,操做系统团队专门为此开发了 fork2 技术,与 Linux Native fork 的关键区别在于能够指定 PID 来 fork 一个进程。
pid_t fork2(pid_t pid);
L2 的单个 SNAPSHOT 能够建立多个进程,一对多关系。
两种自研方案的对比
总体来看,方案一的适用场景更广,可是实现成本更高,方案二较适合 FaaS、NBF 这类场景。
Lambda 为了作到快速扩缩容,要求用户的应用以 Function 为单位开发,Lambda Runtime 动态加载 Function 来快速增长实例。
CSE 则经过将一个应用的多个实例启动后,共享相同的指令数据,抽取出不一样的指令数据,每次启动实例只须要加载多实例的差别部分。所以能够透明兼容社区主流技术栈,如Spring Boot,PHP/Java/Python/Node.JS 等。
Serverless 方式应用占用的实例数随时在变化,所以能够多个应用错峰使用同一台机器。
Serverless 的成本优点是能够和 CPU Share &离在线混部等调度技术的成本优点作叠加,能给最终用户一个更优的整体成本。
HSF demo
package com.test.pandora.hsf; import com.alibaba.boot.hsf.annotation.HSFProvider; @HSFProvider(serviceInterface = HelloWorldService.class) public class HelloWorldServiceImpl implements HelloWorldService { @Override public String sayHello(String name) { return "hello : " + name; } }
Spring Boot demo
package com.example.java.gettingstarted; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication @RestController public class HelloworldApplication { @RequestMapping("/") public String home() { return "Hello World!"; } @RequestMapping("/health") public String healthy() { // Message body required though ignored return "Still surviving."; } public static void main(String[] args) { SpringApplication.run(HelloworldApplication.class, args); } }
某电商业务 A:Serverless 化后,机器数量从11台下降到2台(2~10台之间波动),某促销节,服务流量峰值从数千瞬间飙到十多万,CSE 瞬间弹性扩容,从2台-->5台-->10台,流量峰值回落后又缩容到2台。
某电商业务 B:Serverless 化后,机器数量从4台到2台(2~10台之间波动)。
某电商业务 C:以前固定4台机器,Serverless 化完成后,机器数量变成1台(1~4台之间波动),预发可实现0 - 1台实例之间波动。
原文连接 本文为云栖社区原创内容,未经容许不得转载。