构建 AWS Lambda 的自定义运行时系统 - AWS Lambda

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

构建 AWS Lambda 的自定义运行时系统

您可以采用任何编程语言实施 AWS Lambda 运行时。运行时是一个程序,调用函数时,改程序将运行 Lambda 函数的处理程序方法。该运行时系统可包含在函数的部署包中,也可以分布在中。创建 Lambda 函数时,请选择仅限操作系统的运行时系统provided 运行时系统系列)。

注意

创建自定义运行时系统是一个高级用例。如果您想了解有关编译为本机二进制文件或使用第三方现成运行时系统的信息,请参阅 适用于 AWS Lambda 的仅限操作系统的运行时系统

有关自定义运行时系统部署过程的演练,请参阅 教程:构建自定义运行时系统。您还可在 GitHub 的 awslabs/aws-lambda-cpp 上了解以 C++ 实现的自定义运行时。

要求

自定义运行时系统必须完成某些初始化和处理任务。运行时系统会运行函数的设置代码、从环境变量读取处理程序名称,以及从 Lambda 运行时系统 API 读取调用事件。运行时会将事件数据传递到函数处理程序,并将来自处理程序的响应发布回 Lambda。

初始化任务

初始化任务将对函数的每个实例运行一次以准备用于处理调用的环境。

  • 检索设置 – 读取环境变量以获取有关函数和环境的详细信息。

    • _HANDLER – 处理程序的位置(来自函数的配置)。标准格式为 file.method,其中 file 是没有表达式的文件的名称,method 是在文件中定义的方法或函数的名称。

    • LAMBDA_TASK_ROOT – 包含函数代码的目录。

    • AWS_LAMBDA_RUNTIME_API – 运行时 API 的主机和端口。

    有关可用变量的完整列表,请参阅 定义运行时环境变量

  • 初始化函数 – 加载处理程序文件并运行它包含的任何全局或静态代码。函数应该创建静态资源(如开发工具包客户端和数据库连接)一次,然后将它们重复用于多个调用。

  • 处理错误 – 如果出现错误,请调用初始化错误 API 并立即退出。

计入收费的执行时间和超时的初始化计数。当执行触发您的函数的新实例的初始化时,您可以在日志和 AWS X-Ray 跟踪中看到初始化时间。

例 日志
REPORT RequestId: f8ac1208... Init Duration: 48.26 ms Duration: 237.17 ms Billed Duration: 300 ms Memory Size: 128 MB Max Memory Used: 26 MB

处理任务

其运行时,运行时将使用 Lambda 运行时界面来管理传入事件和报告错误。完成初始化任务后,运行时将在一个循环中处理传入事件。在运行时代码中,按顺序执行下面的步骤。

  • 获取事件 – 调用下一个调用 API 来获取下一个事件。响应正文包含事件数据。响应标头包含请求 ID 和其他信息。

  • 传播跟踪标头 – 从 API 响应中的 Lambda-Runtime-Trace-Id 标头获取 X-Ray 跟踪标头。使用相同的值在本地设置 _X_AMZN_TRACE_ID 环境变量。X-Ray SDK 使用此值在服务之间连接追踪数据。

  • 创建上下文对象 – 使用来自 API 响应中的环境变量和标头的上下文信息创建一个对象。

  • 调用函数处理程序 – 将事件和上下文对象传递到处理程序。

  • 处理响应 – 调用调用响应 API 以发布来自处理程序的响应。

  • 处理错误 – 如果出现错误,请调用调用错误 API。

  • 清理 – 释放未使用的资源,将数据发送到其他服务,或在获取下一个事件之前执行其他任务。

Entrypoint

自定义运行时的入口点是一个名为 bootstrap 的可执行文件。引导文件可以是运行时,也可以调用创建运行时的另一个文件。如果部署包的根目录不包含名为 bootstrap 的文件,则 Lambda 将在函数的层中查找该文件。如果 bootstrap 文件不存在或不是可执行文件,则函数将在调用后返回 Runtime.InvalidEntrypoint 错误。

以下是一个 bootstrap 文件示例,该文件使用捆绑版本的 Node.js 在名为 runtime.js 的单独文件中运行 JavaScript 运行时系统。

例 bootstrap
#!/bin/sh cd $LAMBDA_TASK_ROOT ./node-v11.1.0-linux-x64/bin/node runtime.js

在自定义运行时中实施响应流

对于响应流式处理函数responseerror 端点的行为略经修改,允许运行时系统将部分响应流式传输到客户端并以区块形式返回负载。有关特定行为的更多信息,请参阅以下内容:

  • /runtime/invocation/AwsRequestId/response – 从运行时系统传播 Content-Type 标头以发送到客户端。Lambda 通过 HTTP/1.1 分块传输编码,以区块形式返回响应负载。响应流的最大大小为 20MiB。要将响应流式传输到 Lambda,运行时系统必须:

    • Lambda-Runtime-Function-Response-Mode HTTP 标头设置为 streaming

    • Transfer-Encoding 标头设置为 chunked

    • 编写符合 HTTP/1.1 分块传输编码规范的响应。

    • 成功编写响应后,关闭底层连接。

  • /runtime/invocation/AwsRequestId/error – 运行时系统可以使用此端点向 Lambda 报告函数或运行时系统错误,Lambda 也接受 Transfer-Encoding 标头。只能在运行时开始发送调用响应之前调用此端点。

  • 使用 /runtime/invocation/AwsRequestId/response 中的错误后缀报告中游错误 – 要报告运行时系统开始编写调用响应后发生的错误,运行时系统可以选择附加名为 Lambda-Runtime-Function-Error-TypeLambda-Runtime-Function-Error-Body 的 HTTP 尾随标头。Lambda 将此视为成功响应,并将运行时系统提供的错误元数据转发给客户端。

    注意

    要附加尾随标头,运行时必须在 HTTP 请求的开头设置 Trailer 标头值。这是 HTTP/1.1 分块传输编码规范的要求。

    • Lambda-Runtime-Function-Error-Type – 运行时系统遇到的错误类型。此标头由字符串值组成。Lambda 接受任何字符串,但建议您使用 <category.reason> 格式。例如,Runtime.APIKeyNotFound

    • Lambda-Runtime-Function-Error-Body – 有关错误的 Base64 编码信息。