使用自定义运行时支持自定义编程语言
Serverless应用的函数代码都是在FaaS当中运行的,但是在目前为止也只能选择FaaS平台所选择的编程语言开发应用。
FaaS平台所支持的编程语言有限,函数计算只支持Node.js 8和12、java和python,那么在使用不支持的语言或不支持小版本的时候就需要使用自定义运行时。
自定义运行时的原理
运行时(Runtime)是程序运行时所依赖的环境。
FaaS中的运行时就会创建函数所指定的运行环境,比如说函数计算的Node.js运行时,那就包括了Node.js运行环境以及一些内置的模块比如ali-oss、tablestore,除此之外还有Java运行时、Python运行时。
自定义运行时就是自己在FaaS自定义一个运行时环境,比如TypeScript,使用TypeScript来编写代码并且部署到FaaS平台上运行。
先来回顾下FaaS的运行原理
在FaaS当中运行时被预先定义,比如创建函数的时候可以指定runtime:nodejs12,接下来用户通过创建触发器驱动函数执行之后,Faas就会以nodejs12作为运行时来创建函数实例,函数代码也就在nodejs12这个运行时环境中执行。
怎么才能让函数在自己定义的运行时环境中执行?
安装依赖的本质就是要把函数运行所需要的依赖都打包上传至FaaS中,那能不能把函数的运行时也打包上传到Faas当中呢,也让Faas运用你上传的运行时来执行你的代码呢?
FaaS平台的自定义运行
用TypeScript编写代码
把代码和TypeScript的运行时都上传至FaaS中,然后通过特定的配置让FaaS通过自定义的TypeScript运行时来运行你的代码
runtime:custom
告诉FaaS你使用的是自定义运行时
bootstrap ts-node index.js
告诉FaaS函数启动时使用ts-node运行index.js
FaaS平台在运行函数时会有很多参数,这些参数怎么传递给自定义运行时呢?本质上是远程数据通信问题。
最简单点的在自定义运行时中实现一个Http服务,FaaS平台通过http请求把数据传递给自定义运行时。
自定义运行时就是使用自定义编程语言实现的Http服务,需要为你的Http服务指定一个启动命令。
boostrap文件示例
通用的做法把启动命令保存在名字叫做boostrap文件中,FaaS平台在创建函数实例的时候会执行boostrap文件,启动http服务。
把所有请求和参数都转发到Http服务中,让Http服务处理所有的请求。
自定义运行时的实现
源码示例
https://gitee.com/pingfanrenbiji/serverless-class/tree/master/07
实现一个TypeScript运行时,TypeScript为jS代码增加了类型系统,可以大大提升代码的可读性和可维护性。
大多数FaaS平台都不支持TypeScript,如果你想用一个TypeScript去编写一个Serverless应用,通常把代码编译成JavaScript再运行,很明显没有直接执行TypeScript代码高效。
如果想要直接运行TypeScript的代码,可以通过ts-node来实现,所以可以基于ts-node来执行一个TypeScript的运行时,这样就可以直接使用TypeScript来编写Serverless应用了。
首先在本地创建一个TypeScript项目,然后安装必要的依赖,为了把依赖都上传到FaaS,需要将ts-node等相关的依赖都安装到项目的node目录中。
自定义运行时需要实现一个http服务来接收FaaS平台的请求。
所以接下来使用TypeScript来编写一个Http服务
这段代码启动了一个http服务,监控9000端口。
然后在本地测试,通过在安装在项目中的ts-node命令来运行这段代码。
你还要创建一个boostrap文件在文件当中添加启动命令,这样让FaaS知道如何启动自定义运行时。
添加函数计算的template.yaml配置
- • runntime的值必须为custom
- • handler属性这里没有实际的意义,但是必须要填写
将自定义运行时部署到函数计算
其他无法直接安装在安装目录的编程语言,比如golang和最新版本的Node.js自定义运行时又该怎么实现呢?
如果要沿用TypeScript这种自定义启动命令的方式就需要把golang和代码打包,但是golang是直接安装在操作系统上的,依赖系统环境好像无从下手?
实现一个golang运行时
将运行环境和代码打包,这种思想是不是和容器技术很像?
容器技术就是将应用和运行所依赖环境打包为镜像,这样应用就可以轻松迁移和部署。
那能不能把golang的运行环境构建成docker镜像,然后让FaaS平台能支持自定义容器就能实现任意编程语言的运行时了。
FaaS平台也提供了自定义容器的能力
先构建一个容器镜像,然后通过函数的配置告诉FaaS平台使用你的容器镜像,在函数执行的时候FaaS平台会拉取容器镜像并启动容器执行代码。
与前面的TypeScript运行时一样在自定义容器镜像中也需要实现一个Http服务,用来接收FaaS平台所有的请求。
需要准备一个镜像仓库用来存放你的镜像。
函数计算目前只支持容器镜像服务中的镜像,所以你需要构建自定义运行时镜像然后上传到容器镜像服务中,你可以提前在容器服务中创建一个命名空间或镜像仓库,创建完毕之后记住仓库地址。