背景
从部署物理机到虚拟机过程中,云计算通过虚拟化的方式对算力资源进行了更高效的分配。为了更细粒度的分配,容器在云计算发展浪潮中诞生了。那有没有可能再进一步,将一次业务执行作为单元进行算力分配呢?每当执行的时候才分配一次资源,否则不消耗。
答案就是 Serverless。
什么是 Serverless
Serverless (无服务器架构)并不是严格意义上的无服务器,因为无论如何抽象或者封装底层设备,程序总是要有一个服务器作为物理载体才能运行。Serverless 的概念更加强调计算资源的自由扩展,无需手动人工配置。
Serverless 是由事件驱动的全托管计算服务。用户无需管理服务器等基础设施,只需要编写代码和选择触发器(比如 RPC 请求,定时器等)并上传。其余的工作(如实例选择,扩缩容、监控、日志、容灾、部署等)全部由 Serverless 系统托管。
Serverless 通常包含了两个领域 BaaS和 FaaS,其中 BaaS 可以理解成特定类型的托管服务,例如数据库服务、对象存储服务、日志服务等等,而 FaaS 即为云函数计算服务,提供核心的逻辑处理。
Serverless 实践
基于 Kubernetes 的 Serverless framework 有很多,例如 Knative、OpenFaaS、OpenWhisk 等等,这里以 OpenFaaS 为例。
OpenFaaS 部署
OpenFaaS 可以通过 arkade、helm3 以及 manifests yaml 等方式部署,部署后共有以下组件:
为了方便后续函数管理,这里也一并部署了 faas-cli,并配置了 Gateway Service 暴露的入口地址:
OpenFaaS 工作流程
OpenFaaS Gateway
Gateway作为请求网关,当要部署或者调用一个函数的时候,Gateway会将请求转发给Provider(faas-netes),同时会将监控指标发给Prometheus。alertManager会根据需求,调用API自动伸缩函数。
Prometheus & alertManager
收集 Gateway 的 auto-scaling 指标,结合实际情况,自动伸缩函数的规模。
NATS Streaming
NATS Streaming 是由 NATS 驱动的数据流系统,在保证吞吐量和时延的基础上,解决了Nats消息投递一致性的问题。在 OpenFaaS 中作为处理函数调用的低延迟队列。
faas-netes
faas-netes 是faas-provider 的官方实现。
faas-provider 中定义了一些基本的 faas handler规范,如下所示:
OpenFaaS 使用
OpenFaaS 创建函数可以通过 REST API,faas-cli 或者 GateWay UI 三种方式创建,这里以 faas-cli 为例:
下载模版
首先下载官方提供的语言模版,模版支持 go,java11,python2(3),php7(8),ruby 等诸多语言
生成应用
通过 faas-cli new 创建一个 go 应用,修改 handler 函数,简单模拟一个计算服务(计算入参的和):
#FormatImgID_10#
构建镜像
#FormatImgID_11#
部署应用
#FormatImgID_12#
服务访问
#FormatImgID_13#
也可以通过界面访问或者部署服务
#FormatImgID_14#
自动扩缩容
#FormatImgID_15#
可以通过 label 的配置,将服务默认为0副本,当请求到达时,会根据副本范围、缓冲期,扩缩模式等规格自动扩容,请求结束后,并自动缩容。
OpenFaaS 自动扩缩容源码分析
Prometheus将监控指标发给alertManager之后,alertManager会调用 /system/alert接口,这个接口的handler是由handlers.MakealertHandler方法生成。MakealertHandler方法接收的参数是ServiceQuery。ServiceQuery是一个接口,它有两个函数,用来获取或者设置最大的副本数。
MakealertHandler的函数主要是从http.Request中读取body,然后反序列化成Prometheusalert对象:该对象是一个数组类型,支持对多个函数进行缩放。反序列化之后,调用handlealerts方法,而handlealerts对alerts进行遍历,针对每个alerts调用了scaleService方法。scaleService才是真正处理伸缩服务的函数。
Serverless 使用场景
在了解 Serverless 的应用场景之前,首先总结一下它的技术特点:
快速迭代与部署
高并发、高弹性
稳定、可靠、安全
运维与成本控制
如果应用复杂有显著的波峰波谷、对快速迭代有强烈诉求,Serverless 就可以发挥显著的作用。
但是,由于Serverless 的无状态性,状态管理和共享仍然很困难,因此在使用场景下也具有局限性。
综合而言,Serverless 比较适合以下场景:
机器学习及 AI 模型处理
图片处理、文件处理以及流处理
IoT 后端及移动后端
Serverless 的价值
无服务器管理
无需预置或维护任何服务器。无需安装、维护或管理任何软件或运行时。
灵活扩展
应用程序可自动扩展,或通过切换占用资源(如吞吐量、内存)的单位数(而不是切换单个服务器的单位数)来调整容量,从而实现扩展。
按价值付费
为一致的吞吐量或执行持续时间(而不是服务器单元)付费。
自动化的高可用
无服务器应用程序提供内置可用性和容错功能。无需构建这些功能,因为运行此应用程序的服务在默认情况下会提供这些功能。
Serverless 现阶段的不足
状态管理
要想实现自由的缩放,应用的无状态是必须的,而对于有状态的服务而言,使用 Serverless 就丧失了灵活性,有状态服务需要与存储交互就不可避免的增加了延迟和复杂性。
延迟
应用程序中不同组件的访问延迟是一个大问题,传统架构中可以通过专有的网络协议、RPC 调用、实例拓扑等方面优化,而 Serverless 应用程序是高度分布式、低耦合的,这就意味着延迟将始终是一个问题,单纯使用 Serverless 的应用程序是不太现实的。
结语
Serverless 的出现能够解决备份容灾、计费方式、弹性伸缩、资源分配的等棘手问题,尽管现阶段 Serverless 架构存在很多不足,但是诸多的优良特性决定它是大势所趋。随着Serverless 生态圈多样化发展,它无疑是非常令人期待并且前景光明的方向。