使用 Lambda SnapStart 处理唯一性
调用在 SnapStart 函数上纵向扩展时,Lambda 使用单个初始化的快照来恢复多个执行环境。如果您的初始化代码生成了快照中包含的唯一内容,则跨执行环境重复使用该内容时,该内容可能不是唯一的。若要在使用 SnapStart 时保持唯一性,则必须在初始化后生成唯一的内容。这包括唯一的 ID、唯一的密钥和用于生成伪随机性的熵。
我们推荐使用以下最佳实践来帮助您保持代码的唯一性。对于 Java 函数,Lambda 还提供了开源 SnapStart 扫描工具,以帮助检查假设唯一性的代码。如果您在初始化阶段生成唯一的数据,则可以使用运行时挂钩来还原唯一性。使用运行时挂钩,您可以在 Lambda 拍摄快照之前立即运行特定代码,也可以在 Lambda 从快照恢复函数后立即运行特定代码。
避免在初始化期间保存依赖唯一性的状态
在函数的初始化阶段,避免缓存旨在保持唯一性的数据,例如生成用于日志记录的唯一 ID 或为随机函数设置种子。相反,建议您在函数处理程序中生成唯一的数据或为随机函数设置种子 – 或使用运行时钩子。
以下示例演示如何在函数处理程序中生成 UUID。
使用加密安全伪随机数生成器(CSPRNG)
启用 SnapStart 后,Lambda 将为函数执行环境生成快照,快照包含全部应用程序内存与系统内存。这意味着每个随机数生成器(RNG)的内部状态会完整保留快照捕获瞬间的值,同时应用程序及其依赖项已生成、存放在内存缓冲区中的所有随机字节也一并保留。
当 Lambda 从快照恢复执行环境时,会使用全新熵为 /dev/random、/dev/urandom 对应的内核随机数生成器重新设置种子。直接从这类设备读取随机数的软件,在 SnapStart 下可维持随机性。
如果您的应用程序依赖随机性,我们建议您使用加密安全的随机数生成器(CSPRNG)。除 AL 提供的 OpenSSL 外,支持 SnapStart 的 Lambda 托管运行时(Java 11 及以上、Python 3.12 及以上、.NET 8 及以上)内置以下密码学安全伪随机数生成器(CSPRNG):
-
Java:
java.security.SecureRandom -
Python:
random.SystemRandom -
.NET:
System.Security.Cryptography.RandomNumberGenerator
注意
对于 Go Lambda 运行时,若函数使用标准库的 crypto/rand,则无需修改,该组件默认兼容 SnapStart。
将函数打包为容器映像时,基础映像决定其与 SnapStart 的兼容特性:
-
托管运行时对应的 Lambda 基础映像(Java 11 及以上、Python 3.12 及以上、.NET 8 及以上):如上所述,可兼容 SnapStart。
-
provided.al2023 基础映像:若编程语言运行时从
/dev/random、/dev/urandom,或是 Amazon Linux 2023 软件包列表内列出、兼容 SnapStart 的 OpenSSL 构建包(openssl-snapsafe-libs)获取熵源,则可兼容 SnapStart。若运行时依赖其他熵源,请按照下文“自定义基础映像”中的步骤操作。 -
自定义基础映像:审计加密库,并使用恢复后运行时挂钩,丢弃所有已缓存随机数生成器(RNG)状态与缓冲随机字节,确保库在环境恢复后从系统读取全新熵。例如,使用
rand::rngs::ThreadRng的 Rust 函数,必须在环境恢复后调用reseed()。建议尽可能采用 Lambda 基础映像来构建函数。特别注意:若基础映像自带 OpenSSL 版本或是 OpenSSL 衍生分支(如 BoringSSL、LibreSSL),请改用 provided.al2023 基础映像(内含兼容 SnapStart 的 OpenSSL 构建包:openssl-snapsafe-libs),或使用 AWS libcrypto(AWS-LC)。
最低支持的库版本
AWS 加密库会自动保持 SnapStart 的随机性,从下表中指定的最低版本开始。如果您将这些库与 Lambda 函数一起使用,请确保使用以下最低版本或更高版本:
| 库 | 支持的最低版本(x86) | 支持的最低版本(ARM) |
|---|---|---|
| AWS libcrypto(AWS-LC) |
1.16.0 |
1.30.0 |
| AWS libcrypto FIPS |
2.0.13 |
2.0.13 |
如果通过以下库将上述加密库与 Lambda 函数打包为可传递依赖项,请确保使用以下最低版本或更高版本:
| 库 | 支持的最低版本(x86) | 支持的最低版本(ARM) |
|---|---|---|
| AWS SDK for Java 2.x |
2.23.20 |
2.26.12 |
| AWS Common Runtime for Java |
0.29.8 |
0.29.25 |
| Amazon Corretto 加密提供商 |
2.4.1 |
2.4.1 |
| Amazon Corretto 加密提供商 FIPS |
2.4.1 |
2.4.1 |
以下示例演示如何使用 CSPRNG 来保证唯一的编号序列,即使从快照中还原函数也是如此。
SnapStart 扫描工具(仅 Java)
Lambda 为 Java 提供了扫描工具,以帮助您检查假设唯一性的代码。SnapStart 扫描工具是一个开源 SpotBugs
要详细了解如何使用 SnapStart 处理唯一性,请参阅 AWS 计算博客上的通过 AWS Lambda SnapStart 加快启动速度