本文介绍Custom Runtime的背景信息、基本原理、执行环境、配置要求、公共请求头及日志规范,您可以参见这些信息打造属于您的自定义运行环境。
背景信息
Custom Runtime就是自定义的运行环境。基于Custom Runtime您可以实现:
- 定制个性化语言(例如Go、Lua、Ruby)和各种语言的小版本(例如Python 3.7、Node.js 14)的执行环境,打造属于您的运行环境。
- 一键迁移现有的Web应用或基于传统开发的Web项目到函数计算平台。
基本原理
Custom Runtime本质上是一个HTTP Server,您只需要搭建一个具有监听端口的HTTP Server,创建一个启动目标Server的可执行文件bootstrap,然后将该文件和您的代码文件一起打成ZIP包,最后以该ZIP包作为代码包创建一个Custom Runtime的函数。
函数计算冷启动Custom Runtime时,会默认调用bootstrap文件启动您自定义的HTTP Server。然后这个HTTP Server接管了函数计算系统的所有请求,包括来自您的事件函数调用及HTTP函数调用。
您在开发函数具体的逻辑之前,一般会确认开发的函数是事件函数还是HTTP函数,原理如下所示。
- 事件函数
- HTTP函数
执行环境
Custom Runtime内置支持以下语言,您可以直接创建以下语言的Custom Runtime,无需安装第三方解释器。
- Python 3.7.4版本
- Node.js 10.16.2版本
- PHP 7.4.12版本
- Ruby 2.7版本
- PowerShell 7.1.0版本
- Open JDK 1.8.0(Open JDK Version 1.8.0_232)
关于Custom Runtime的内置软件,请参见详细信息。
HTTP Server配置要求
创建HTTP Server时您需要满足以下要求:
- Custom Runtime启动的服务一定要监听
0.0.0.0:CAPort
或*:CAPort
端口。如果您使用127.0.0.1:CAPort
端口,会导致请求超时,出现以下错误:{ "ErrorCode":"FunctionNotStarted", "ErrorMessage":"The CA's http server cannot be started:ContainerStartDuration:25000000000. Ping CA failed due to: dial tcp 21.0.5.7:9000: getsockopt: connection refused Logs : 2019-11-29T09:53:30.859837462Z Listening on port 9000" }
Custom Runtime的监听端口( CAPort) 默认是9000。如果Custom Runtime使用默认的监听端口,那么您实现的Custom Runtime的HTTP Server监听的端口也必须是9000。 如果Custom Runtime使用的监听端口是8080,那么您实现的Custom Runtime的HTTP Server监听的端口也必须是8080。
- Custom Runtime的bootstrap文件,如果是shell脚本一定要添加
#!/bin/bash
,否则会出现以下错误:{ "ErrorCode":"CAExited", "ErrorMessage":"The CA process either cannot be started or exited:ContainerStartDuration:25037266905. CA process cannot be started or exited already: rpc error: code = 106 desc = ContainerStartDuration:25000000000. Ping CA failed due to: dial tcp 21.0.7.2:9000: i/o timeout Logs : 2019-11-29T07:27:50.759658265Z panic: standard_init_linux.go:178: exec user process caused \"exec format error\" }
如果是二进制可执行文件,例如Go,C++直接编译出来的目标二进制文件,则不需要添加
#!/bin/bash
。 - Custom Runtime的bootstrap文件,一定要具备777或755权限,否则会出现以下错误:
{ "ErrorCode":"CAFilePermission", "ErrorMessage":"The CA process cannot be started due to bootstrap file don't have execute permissions }
您可以通过以下方式解决该问题:- 在打包文件前执行chmod 777 bootstrap或chmod 755 bootstrap命令。
- 如果您使用的是Windows操作系统,您需要将bootstrap文件格式修改为UNIX格式。
- Connection需要设置为Keep-Alive,Server端请求超时时间需设置在15分钟及以上。示例如下:
//例如Node.js使用express时。 var server = app.listen(PORT, HOST); server.timeout = 0; // never timeout server.keepAliveTimeout = 0; // keepalive, never timeout
- HTTP Server需要在30秒内启动完毕。
函数计算公共请求头
Custom Runtime从函数计算系统中接收到的公共请求头如下表所示。如果您需要访问阿里云其他服务,您可能需要用到临时AccessKey的Headers。如果您需要迁移已有的应用,可忽略下文的内容。
- 事件函数和HTTP函数均包含Common Headers。
- 公共请求头是函数计算系统自动生成的,主要包含权限、函数的基本信息等。
Header | 描述 |
---|---|
x-fc-request-id | Request ID。 |
x-fc-access-key-id | 临时AccessKey ID。 |
x-fc-access-key-secret | 临时AccessKey Secret。 |
x-fc-security-token | 临时Security Token。 |
x-fc-function-handler | 函数的Handler,如果Runtime本身就是函数,则该值是没有意义的。 |
x-fc-function-memory | 函数最大能使用的内存。 |
x-fc-function-initializer | Initializer函数的Handler,如果Runtime本身就是函数,则该值是不需要的。 |
x-fc-initialization-timeout | Initializer函数执行的超时时间。 |
x-fc-region | 函数所在的地域。 |
x-fc-account-id | 函数所有者的UID。 |
x-fc-qualifier | 函数调用时指定的服务版本或别名。更多信息,请参见查看执行函数的版本。 |
x-fc-version-id | 函数版本。 |
x-fc-service-name | 函数所在的服务的名字。 |
x-fc-service-logproject | 函配所在服务配置的日志项目。 |
x-fc-service-logstore | 函数所在服务配置的日志仓库。 |
x-fc-control-path | 请求的类型。 |
函数日志格式
推荐您在创建服务时使用日志服务SLS,Custom Runtime中所有打印到标准输出(Stdout)的日志会被自动收集到您指定的日志服务中。具体步骤,请参见配置并查看函数日志。
函数计算系统在其他运行环境(除Custom Runtime及Custom Container Runtime外)中调用函数时,请求头中包含x-fc-log-type" = "Tail"
,那么返回的响应头包含x-fc-log-result
的内容就是函数执行时打印的日志,日志大小最大为4 KB。您可以在函数计算控制台函数执行结果中查看该日志。如果您希望在控制台的执行结果中看到Custom Runtime的运行日志,您需要在代码中记录请求开始和结束日志。
内容 | 是否必选 | 代码 |
---|---|---|
启动Runtime | 否
说明 该内容为函数冷启动的标志。
|
FunctionCompute ${runtime} runtime inited. 说明 如果您使用Go开发,
${runtime} 可以为Go自定义,但最好不要使用官方的语言名称,例如Node.js、Python、PHP等。
|
Invoke开始的日志 | 是 | FC Invoke Start RequestId: ${RequestId} |
Invoke结束的日志 | 是 | FC Invoke End RequestId: ${RequestId} |
Initialize开始的日志 | 否
说明 如果是Initializer函数,则需要记录。
|
FC Initialize Start RequestId: ${RequestId} |
Initialize结束的日志 | 否
说明 如果是Initializer函数,则需要记录。
|
FC Initialize End RequestId: ${RequestId} |
$utcdatetime(yyyy-MM-ddTHH:mm:ss.fff) $requestId [$Level] $message
。
示例
函数类型 | 示例类型 |
---|---|
事件函数 | |
HTTP函数 |
更多信息
Custom Runtime的限制信息,请参见资源使用限制。