全部产品
云市场

Custom Runtime 用户手册

更新时间:2019-09-23 09:54:26

Custom Runtime 手册

什么是 Custom Runtime

顾名思义, Custom Runtime 就是自定义的执行环境, 用户基于 Custom Runtime 可以完成以下目标:

  • 可以随心所欲持定制个性化语言执行环境(例如 golang、lua、ruby)以及各种语言的小版本(例如python3.7、Nodejs12)等,打造属于自己的自定义runtime

  • 现有的 web 应用或基于传统开发 web 项目基本不用做任何改造,即可将项目一键迁移到函数计算平台

Custom Runtime 基本原理

cr

如上图所示,Custom Runtime 本质上是一个 HTTP Server, 用户只需要实现一个监听固定端口的 Http server, 将启动这个 server 的命令保存为一个名叫 bootstrap 的文件,最后一起zip打包作为代码包创建一个custom runtime的函数。

FC 系统冷启动 Custom Runtime 的时候, 会默认调用 bootstrap 启动用户自定义的 HTTP Server, 之后这个 HTTP Server 接管了 FC 系统所有请求(来自用户的普通调用或者 HTTP Trigger 调用):

普通调用

FC 系统会将 Common Headers 和用户调用请求的 Body 转发给 Custom Runtime

注:Common Headers 里面的信息可以构造类似官方 runtime 中的入参 context,而用户请求的 Body 可以构造类似官方 runtime 中的入参 event

如果您没有对普通调用函数定义为 def handler(context, event) 的需求, 您直接基于这个 HTTP Server 实现自定义逻辑就好

HTTP Trigger 调用

FC 系统会将用户的请求(包括 Path,headers以及body)加上 Common Headers 转发给 Custom Runtime, 因此, 如果对 common headers 不感兴趣, 那么基于 Custom Runtime 可以快速移植一个已有的 web App。

执行环境

Custom Runtime 的 docker image 基于 debian 9(stretch),其中 linux 内核为 Linux version 4.9.125,其中对于python, nodejs 和 java 提供了内置支持:

  • python 3.7.4
  • nodejs v10.16.2
  • open jdk 1.8.0

    openjdk version “1.8.0_222”OpenJDK Runtime Environment (build 1.8.0_222-8u222-b10-1~deb9u1-b10)

最简单的 Custom Runtime

用户要实现一个最简单的 Custom runtime,只要符合以下两条:

  • 创建一个http server,监听在固定端口(端口可以读取环境变量 FC_SERVER_PORT,默认为 9000)
  • http server 需要在 15s 内完成启动

比如函数计算运行一个 tornado Application, server.py 代码如下:

  1. import tornado.ioloop
  2. import tornado.web
  3. import os
  4. class MainHandler(tornado.web.RequestHandler):
  5. def get(self):
  6. self.write("GET: Hello world")
  7. def post(self):
  8. self.write("POST: Hello world")
  9. def make_app():
  10. return tornado.web.Application([
  11. (r"/.*", MainHandler),
  12. ])
  13. if __name__ == "__main__":
  14. app = make_app()
  15. port = os.environ.get("FC_SERVER_PORT", "9000")
  16. app.listen(int(port))
  17. tornado.ioloop.IOLoop.current().start()

然后编写一个具有可执行权限的名字为bootstrap (注:#!/bin/bash注释是必需的)文件启动上面代码的 http server:

  1. #!/bin/bash
  2. python server.py

最后一起 zip 打包, 然后基于这个 zip 包创建 runtime 为 custom 的函数即可:

注:此时函数的 handler 没有任何实质意义, 填写任意的一个满足 FC handler 字符集约束的字符串即可

  1. root@33a2b0c2a9d7:/code# ls -ll
  2. total 16
  3. -rwxr-xr-x 1 root staff 17 Aug 16 22:19 bootstrap
  4. -rw-r--r-- 1 root staff 414 Aug 16 17:24 server.py
  5. drwxr-xr-x 38 root staff 1216 Aug 16 22:20 tornado
  6. root@33a2b0c2a9d7:/code# zip -r code.zip *
  7. root@33a2b0c2a9d7:/code# ls -ll code.zip
  8. -rw-r--r-- 1 root staff 943389 Aug 16 22:24 code.zip

接下来完整的介绍 Custom Runtime 可以实现的功能以及接口要求(可选)。

FC 公共请求 Headers

如上节所述, 用户只需要启动一个 Http server 即可,但作为一个Http Server,用户可能会关心会收到什么 Header。以下这些 Request Headers 是 Custom Runtime 会从FC系统中接收到的。如果需要访问阿里云其他服务,你可能需要用到用户临时AK的headers。 如果您是移植已有的App,你可能不必理会如下表所示的任何Headers。

Header 描述
x-fc-request-id Invoke/Initialize request Id
x-fc-access-key-id 临时 access key id
x-fc-access-key-secret 临时 access key secret
x-fc-security-token 临时 security token
x-fc-function-handler 函数的 handler, 如果 runtime 本身和函数完全是绑定的,该值是没有意思的
x-fc-function-memory 函数最大能使用的 memory (in MB)
x-fc-function-initializer 函数的 Initializer,如果 runtime 本身和函数完全是绑定的,则该值是不需要的。
x-fc-initialization-timeout Initializer 执行的 timeout时间
x-fc-region 函数所在的 region
x-fc-account-id 函数 owner 的 uid
x-fc-qualifier 函数 qualifier
x-fc-version-id 函数 version
x-fc-service-name 函数所在的 Service 的 Name
x-fc-service-logproject 函配所在 Service 配置的 SLS log project
x-fc-service-logstore 函数所在 Service 配置的 SLS log store
x-fc-control-path 请求的类型

/invoke: 非 http trigger invoke请求/initialize: initialize 请求/http-invoke: http trigger 的 invoke 请求 |

日志格式

推荐用户在创建服务时使用日志服务,当使用日志服务时,Custom Runtime中所有输出到 Console 的日志会被保存到你指定的日志服务中

函数计算系统其他 Runtime 具有这样一个功能: 当用户调用函数的时候, 请求的 header 中包含 “x-fc-log-type” = “Tail” , 那么返回的 response 中 header 为 x-fc-log-result 的内容就是函数执行时候打印的日志, 日志内容最大为 4KB。

目前函数计算的控制台显示的日志就是基于这个功能实现。如果您对于该功能没有需求, 可以忽略下面的内容。

1.Runtime 启动(option,冷启动的标志)

FunctionCompute ${runtime} runtime inited.

比如你用 go 开发, ${runtime} 可以为 golang,自定义,但最好不要和官方的 nodejs 、python、 php 等重名

2.Invoke开始的Log(required)

FC Invoke Start RequestId: ${RequestId}

3.Invoke结束的Log(required)

FC Invoke End RequestId: ${RequestId}

4.Initialize开始的Log(option, 有Initialize的才需要)

FC Initialize Start RequestId: ${RequestId}

5.Initialize结束的Log(option, 有Initialize的才需要)

FC Initialize End RequestId: ${RequestId}

除了以上特殊的message之外,推荐用户自己的日志包含请求$requestId,方便日后诊断问题, 例如 format 为:$utcdatetime(yyyy-MM-ddTHH:mm:ss.fff) $requestId [$Level] $message

HTTP Server配置要求

Http Server配置要求:

  • 监听在 any ip 的 指定端口(端口可以读取环境变量 FC_SERVER_PORT,默认为 9000)
  • connection keep alive
  • request timeout 至少10分钟以上
  • HttpServer在 15s 之内启动完毕

普通调用和 HTTP Trigger调用

对于 Custom runtime, Http Trigger调用和普通调用(非 http trigger调用),可以根据 header x-fc-control-path 判别:

  • /invoke,该请求为非http trigger。当值是/invoke时,表示该请求是一次 invoke 调用
  • /http-invoke ,该请求为http trigger, /http-invoke表示是一个http invoke调用,函数计算会将用户的请求(包括 Path,headers以及body)加上上述 common headers 之后转发给 Custom runtime, Custom runtime 返回的 headers以及 Body则会被返回给客户端
  • /initialize, 第一次调用函数创建执行环境,系统自动发起的 initialize 调用

Custom Runtime 普通调用

Path x-fc-control-path 输入Request 期望的Response
POST / /invoke Body:函数输入(InvokeFunction时指定的Payload).
Headers:Common Request Headers
Body: 函数handler的返回值,Success Status: 200,Failure Status: 404 (通过 headerx-fc-status)
POST / /initialize Body:
Headers:Common Request Headers
Body: 成功时无Body,Success Status: 200,Failure Status: 404 (通过header x-fc-status)

Custom Runtime HTTP Trigger 调用

当函数是http trigger调用时,用户函数提供的 Web API/Web Page 将直接被用户端访问,因此无需实现 non-http trigger时所实现的 /invoke 以及 /initialize 接口,完全由用户自定义,Custom runtime 会收到除 common headers 之外的以下 headers:

Header 描述
x-fc-base-path 当用户尚未配置自定义域名时,x-fc-base-path的值是/2016-08-15/proxy/${servicename}/${functionname}/, 用户代码可能需要将该值设定为 Web App 的 Path Base, 不同语言或框架有不同的处理。

Custom Runtime 的限制

和其他runtime一样,参见:限制项