为容器映像实现 SnapStart 挂钩
概述
将 SnapStart 与容器映像函数搭配使用时,运行时需协调函数生命周期,并在对应生命周期阶段调用快照前挂钩与恢复后挂钩。您可借助这些挂钩,在快照-恢复生命周期的特定节点运行自定义逻辑(例如刷新凭证、为随机数生成器重新设置种子)。若使用支持 SnapStart 的托管运行时,或对应运行时的基础映像(Java 11+、Python 3.12+、.NET 8+),Lambda 将自动协调生命周期。请按照在 Lambda 函数快照之前或之后实现代码所述,通过 API 注册挂钩。
若使用自定义基础容器映像、运行时接口客户端(RIC),或是 Lambda 为 provided.al2023、Node.js、Ruby 提供的基础映像,请按本页面步骤启用 SnapStart。
先决条件
当 Lambda 从快照恢复函数时,初始化阶段定义的所有状态(如随机数生成器、唯一 ID、缓存凭证)会在由此快照恢复的全部执行环境间共享。在为基于容器映像的 Lambda 函数启用 SnapStart 前,请查阅使用 Lambda SnapStart 处理唯一性,并确保满足使用加密安全伪随机数生成器(CSPRNG)中列出的各项要求。
确认已满足全部要求后,请从以下两个选项中选择一项:
-
选项 1:若需要在恢复函数快照时,通过快照前挂钩和恢复后挂钩运行自定义逻辑,请按照实现 SnapStart 生命周期挂钩章节所载说明操作。
-
选项 2:若无需使用这些挂钩,可在 Dockerfile 内指定以下标签,为该容器映像启用 SnapStart:
LABEL com.amazonaws.lambda.feature.snapstart="Allow"
若容器映像既未实现 /restore/next API,也未设置该标签,版本发布将会失败。
注意
若采用适用于 Java(11+)、Python(3.12+)、.NET(8+)的 Lambda 托管基础映像,则无需满足这些先决条件,因为这类映像已完成 SnapStart 生命周期协调,且满足唯一性要求。
生命周期概述
下图展示 SnapStart 自定义运行时需要执行的运行时 API 调用顺序。所有调用均属于 Runtime API 合约;其中 #3、#4、#5、#6 调用为 SnapStart 专用。
实现 SnapStart 生命周期挂钩
若要在容器映像函数上使用 SnapStart,请按以下步骤操作:
-
运行快照前挂钩并触发快照流程:在函数初始化代码的最后一步,按需执行快照前挂钩,触发快照流程。仅当 SnapStart 已启用时才执行上述步骤,可通过校验
AWS_LAMBDA_INITIALIZATION_TYPE境变量的值是否等于snap-start进行判断。执行已注册的快照前挂钩,再调用GET /runtime/restore/next触发快照流程。若快照前挂钩抛出异常或返回错误,运行时会将该错误上报至/runtime/init/error端点。请参见下方伪代码示例:# After all initialization code has finished: READ initialization_type FROM environment variable "AWS_LAMBDA_INITIALIZATION_TYPE" IF initialization_type IS "snap-start" THEN TRY EXECUTE registered before-snapshot hooks ON ERROR POST error to /runtime/init/error SET header Lambda-Runtime-Function-Error-Type TO <Category>.<Reason> SET body TO { errorMessage, errorType, stackTrace } EXIT process with non-zero code # Signal readiness for snapshot SEND GET request to /runtime/restore/next # The request blocks until Lambda restores the execution environment from the snapshot, then returns HTTP 200. END IF注意
初始化阶段与快照前挂钩共用总超时时间:
max(function_timeout, 130 seconds)。若超出该时限,Lambda 会使 PublishVersion 请求失败。此外,与/runtime/invocation/next类似,/runtime/restore/next调用为阻塞调用。该调用会保持阻塞,直至 Lambda 从快照恢复执行环境。 -
运行恢复后挂钩,随后进入调用循环。当
GET /runtime/restore/next返回 200 时,运行时必须先执行全部已注册的恢复后挂钩,之后才能进入调用循环。若恢复后挂钩执行失败,请向/runtime/restore/error上报错误。恢复后挂钩执行完毕后,调用GET /runtime/invocation/next进入标准调用循环。自此之后,函数行为与未启用 SnapStart 的函数完全一致。请参见下方伪代码示例:# After the snapshot has been restored # (i.e., GET /runtime/restore/next has returned HTTP 200): TRY EXECUTE registered after-restore hooks ON ERROR POST error to /runtime/restore/error SET header Lambda-Runtime-Function-Error-Type TO <Category>.<Reason> SET body TO { errorMessage, errorType, stackTrace } # Proceed to the invoke loop
错误处理
若挂钩执行失败,运行时必须向对应的 API 端点上报错误,并退出进程。下表汇总各阶段的处理行为:
| 阶段 | 错误 API 端点 | 失败后会怎样 |
|---|---|---|
| 初始化/快照前 | POST /runtime/init/error |
Lambda 会使 PublishVersion 请求失败。退出进程。 |
| 恢复后 | POST /runtime/restore/error |
Lambda 会将正在进行的调用标记为失败,并销毁执行环境。退出进程。 |
对于这两个 API 端点,请将 Lambda-Runtime-Function-Error-Type 标头设为 <Category.Reason> 格式的值(例如 Runtime.BeforeSnapshotError 或 Runtime.AfterRestoreError)。错误正文需包含 TerrorMessage、errorType,以及可选的 stackTrace。
如需完整的 API 端点规范与响应码,请参见 Runtime API 参考中的 初始化错误 和 恢复错误(仅适用于 SnapStart)。