FaaS - Runtime
概述
- 一般的编程语言都有自身的运行时,运行时的主要职责是可以让
代码和机器交互
,进而实现业务逻辑 - 函数计算运行时
- 能够让
函数
在机器
或者容器
中执行起来,实现业务逻辑的执行环境
- 通常由特定语言构建的
框架
构成
- 能够让
函数计算运行时
依赖于语言运行时
- 函数计算运行时的本质:让函数在容器中执行起来的
代码框架
- 在
函数实例
初始化时,函数计算运行时
一般会由一个初始化进程
加载起来 - 然后
函数计算运行时
就可以准备接收请求 - 当请求到达后,业务代码会被对应的
语言运行时
中加载进来处理请求
Runtime
是一个特定语言
环境下的服务框架
环境
- 该服务将以一个
进程
的形态运行在用户容器
中,并与用户代码相关联 - 该服务启动后,会一直等待请求的到来,一旦请求到达后,Runtime 会
关联
业务代码去执行(并发
)
原理
语言类型
编译型语言
- C/C++/Go,在编译时将所有用到的静态依赖、源码一起打包,编译完后可以直接运行
- Java,经过编译产生的字节码需要 JVM 再次将其转换为机器码,同时具有编译型和解释型的特性
- 通常需要将所有依赖包打包成一个 jar 包或者 war 包,符合编译型语言的风格
- 在开发函数时,需要
强依赖
平台提供的包- 需要将业务代码和运行时生成一个完整的二进制文件、jar 包或者 war 包
解释型语言
- Python/Node.js,只需要通过解释器执行,可以做到业务代码与依赖
分离
Go Runtime
对于编译型语言,用户代码需要与运行时
一起编译
,云厂商一般会将编译型语言的运行时开源
获取请求
- FaaS 平台提前将
RUNTIME_API
写到环境变量
里 - Runtime 会通过初始化客户端对象 runtimeAPIClient,从该
接口
中获得到请求
关联 UserHandler
- UserHandler 在 Go Runtime 中
- 是通过
反射机制
获取的,并将 UserHandler 封装到一个统一格式
的结构体Handler
中
- 是通过
- 再将
Handler
作为Function
结构体类型的一个属性
进行赋值
调用 UserHandler
在获取
请求
和UserHandler
后,可以使用上一步创建的 Function 对象去执行请求
Python Runtime
运行时作为一个容器进程,不断地等待请求的到来,其
生命周期
和函数容器实例
是保持一致的
1 | root@s-62c8e50b-80f87072536d411b8914:/code# ps -ef |
- 1 号进程为函数实例启动的初始进程
- 4 号进程是通过 1 号进程
Fork
出来的,即Python Runtime
bootstrap.py
为 Python Runtime 的入口
核心流程
1 | def main(): |
- 服务初始化
- 日志初始化、设置并发模式下的全局参数
- 通过环境变量
FC_RUNTIME_API
对应的服务地址,构造之后获取请求的客户端
- 获取请求
- 使得客户端不断获取请求信息
- 根据请求信息执行用户代码
- 在多并发情况下,
Python
使用线程
,而Go
使用的是协程
- 在多并发情况下,
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.