本文介绍Custom Container事件函数的背景信息及代码示例。

背景介绍

在Custom Container Runtime中,函数计算系统会将Common Headers、Body、POST方法以及/invoke/initialize路径转发给容器中的HTTP Server。您可以选择实现类似官方支持的Runtime(例如Golang Runtime)的context、event这样的函数签名。您也可以直接使用入参请求头(Headers)和请求体 (Body)来编写函数的业务逻辑。更多信息,请参见Custom Runtime事件函数调用

函数判断

对于Custom Container Runtime,您可以根据Headers中的x-fc-control-path来判断HTTP函数调用和事件函数调用。

说明 通常情况下,您无需关注x-fc-control-path字段。
  • /invoke:该请求为事件函数调用。/invoke表示是Invoke函数调用请求。
  • /initialize/initialize表示第一次创建执行环境时,函数计算系统自动发起的Initialize函数调用请求。在容器的生命周期内,有且仅成功调用一次,类似于Class构造函数。
  • /http-invoke:该请求为HTTP函数调用。/http-invoke表示是一个HTTP Invoke函数调用请求。函数计算会将您的请求(包括Method、Path、Body、Query及Headers)加上Common Headers后转发给Custom Container Runtime,Custom Container Runtime返回的响应头和响应体则会被返回给客户端。

函数调用说明

当函数是事件函数调用时,仅需实现事件函数调用时所实现的Path,即/invoke/initialize
注意 如果创建的函数不设置Initializer,就无需实现/initialize。当不设置时,即使HTTP Server实现了/initialize,代码中的/initialize逻辑也无法被调用执行。
Path 输入请求 期望的响应
POST /invoke
  • 请求体:函数输入(InvokeFunction时指定的Payload)。
  • 请求头:Common Request Headers。具体信息,请参见函数计算公共请求头
    注意 Content-Typeapplication/octet-stream
响应体:函数Handler的返回值。
  • StatusCode
    • 200:成功状态。
    • 404:失败状态。
  • Header:x-fc-status
    • 200:成功状态。
    • 404:失败状态。
通过Headers中的x-fc-status响应,向函数计算系统汇报本地函数是否执行成功。
  • 不设置x-fc-status时:函数计算系统默认本次调用是成功执行的,但是您的函数可能有异常,没有向函数计算系统汇报,函数计算系统则会认为这次函数执行没有报错,在业务逻辑上可能没有影响,但是在监控可观测性上会有影响。如下图所示。image8hanshujisuanruntime
  • 设置x-fc-status时:当您的函数存在异常,通过x-fc-status的响应向函数系统汇报本次函数执行失败,并将错误堆栈信息打印到日志中。如下图所示。image9runtimefc
说明 在返回的HTTP响应中,建议您同时设置StatusCode和x-fc-status。
(可选)POST /initialize 响应体:函数Initializer的返回值。
StatusCode
  • 200:成功状态。
  • 404:失败状态。

代码示例

在以下Node.js Express示例中,POST方法和/initialize路径会在函数实例初始化时被函数计算调用,POST方法和/invoke路径为函数计算被调用时的Handler,通过req.headers以及req.body获取context、event并将函数返回结果通过HTTP Response结构体输出。

'use strict';

const express = require('express');

// Constants
const PORT = 9000;
const HOST = '0.0.0.0';


// initialize example, need config Initializer in function meta 
app.post('/initialize', (req, res) => {
  res.send('Hello FunctionCompute, /initialize\n');
});


// Event function invocation
app.post('/invoke', (req, res) => {
  res.send('Hello FunctionCompute, event function\n');
});

var server = app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);

server.timeout = 0; // never timeout
server.keepAliveTimeout = 0; // keepalive, never timeout