本文介绍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函数,原理如下所示:

  • 事件函数eventfunction
  • HTTP函数HTTPFunction

执行环境

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 bootstrapchmod 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}
除了以上特殊的信息之外,推荐您在自己的日志中包含请求ID,这样可以方便您日后诊断问题,推荐日志格式为 $utcdatetime(yyyy-MM-ddTHH:mm:ss.fff) $requestId [$Level] $message
说明 不同语言下指定日志级别的接口不同,请您根据实际运行环境设置。更多信息,请参见 日志记录

示例

您可以参考以下文档打造属于您的Custom Runtime。
函数类型 示例类型
事件函数
HTTP函数

更多信息

Custom Runtime的限制信息,请参见资源使用限制