1.1 Serverless基础概念
Serverless理念从狭义的解释逐步延伸出更广阔的含义,不过其中蕴含的技术特点有相对统一的共识。下面我们从Serverless理念出发,列举并阐述Serverless技术特点,进而引出在Serverless领域比较具象的FaaS(Function as a Service,函数即服务)、BaaS(Backend as a Service,后端即服务)的产品形态。
1.1.1 Serverless理念
Serverless的概念诞生已久,从2012年Serverless概念首次被提出,到2014年Amazon发布AWS Lambda产品实践Serverless架构模式,再到2018年Gartner将Serverless Computing列为十大未来影响基础设施和运维的技术趋势之一,业界基本认可了Serverless。回顾其10年的发展历程,各大云厂商相继推出Serverless的云产品,开源生态中Serverless的项目也崭露头角,从最初的概念定义到发展中的概念重塑,Serverless逐渐被赋予更加广阔的含义。
1.1.2 Serverless技术特点
Serverless在演进过程中催生了Serverless生态极致弹性、精益成本、快速交付的特性,能助力业务架构的迭代升级。与传统架构相比,Serverless有如下特点。
1.按需使用
Serverless让用户不再关心底层基础设施的产生和管理,Serverless平台会根据服务的实际流量创建计算和存储资源,当服务没有流量时,对应的资源会被自动回收,用户只需要对实际流量消耗的资源进行付费。这种按需使用和付费方式的转变,让整体的资源分配从计划模式走向按需分配模式,不仅让用户受益,也让Serverless平台的运营者可以充分地利用统一调度的优势,不断优化系统,最终达到资源使用效率最大化的目标。
2.弹性伸缩
大多数计算产品根据应用负载和算力来进行扩缩容,而Serverless平台针对请求层面弹性伸缩,其粒度更细。Serverless平台可以获取足够多的请求周边数据,如服务负载信息、请求延迟信息等,对应用实例进行横向和纵向的扩缩容。横向的扩缩容是对流量的反应,更多的流量意味着需要更多数量的实例来承载;纵向的扩缩容是对单个应用实例资源的调整,在单实例、多并发的场景下可以有效地减少应用碎片和额外的系统开销。在平台方收集足够的历史数据后,可以利用机器学习等方式,对流量进行预测来指导扩缩容,提前扩缩容的动作可以让应用实例更加从容地面对流量,减少冷启动请求的“毛刺”,从而使服务状态更加稳定。
3.事件驱动
应用程序被托管在Serverless平台之上,开发者需要通过事件驱动(event driven)的方式来触发对应用程序的调用,Serverless平台一般会提供各式各样的触发器,来联动打通各个基础架构组件。例如针对在线调用,Serverless平台会提供一个网关触发器来承载业务流量。开发者可以轻而易举地接入特定的触发源,更深层次的用意是让Serverless平台有能力感知和控制流量的流入。对于流量的强管控,可以让Serverless平台进行一些并发的控制、限流、无流量的缩零、冷启动流量的实例拉起等操作。因此,事件驱动机制自然成为Serverless中新的计算范式。
4.函数运行时
业内有一个说法:“如果你的PaaS能够在20ms内启动实例并能运行0.5s,就可以将其称为Serverless。”这种说法比较直观,其底层逻辑是表达一种瞬生瞬灭的能力,即当服务实例可以在极短的时间内产生和消亡时,弹性伸缩就会达到极致的效果。快速启动的前提是,应用程序需要在“沙箱”中运行,在不同的应用场景中有不同等级的资源隔离需求,运行时沙箱需要足够轻量,以尽量减少服务运行时所需的系统开销,保证启动速度足够快。
运行时的分层体系如图1-1所示,从上至下,不同的语言会有相应的语言运行时(runtime),解释型语言的用户代码会在运行时被动态加载到各种语言提供的语言运行时中;编译型语言一般会提供一些代码包,一起编译、打包到用户的应用程序中。函数运行时的分层体系针对需要强隔离的场景,会使用轻量虚拟机方式进行隔离;针对私有云内部场景,为了减少虚拟机监控器(hypervisor)的消耗,会使用容器技术中常用的cgroups和namespace进行一些资源基础限制和隔离;针对一些极致轻量级场景,会利用进程沙箱机制,如WebAssembly、V8等技术来进行隔离,以在有限的接口表达和极致冷启动方面寻求最佳平衡。底层宿主机可以使用传统物理机,也可以使用裸金属方案达到底层资源的弹性、灵活供给。
图1-1 运行时的分层体系