本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
缩短 SDK 的启动时间 AWS Lambda
的目标之一 AWS SDK for Java 2.x 是减少 AWS Lambda 函数的启动延迟。SDK 包含可缩短启动时间的更改,本主题末尾将对此进行讨论。
首先,本主题重点介绍为缩短冷启动时间可以进行的更改。这包括更改代码结构和服务客户端的配置。
使用 AWS CRT-based HTTP 客户端
对于使用 AWS Lambda,我们建议使用同步场景和异步AwsCrtAsyncHttpClientAwsCrtHttpClient
本指南中的 配置 AWS 基于 CRT 的 HTTP 客户 主题描述了使用 HTTP 客户端的好处、如何添加依赖项以及如何按服务客户端配置其使用。
移除未使用的 HTTP 客户端依赖项
除了明确使用 AWS CRT-based 客户端外,您还可以移除 SDK 默认引入的其他 HTTP 客户端。当需要加载的库较少时,Lambda 启动时间会缩短,因此您应该移除 JVM 需要加载的所有未使用的构件。
以下 Maven pom.xml 文件片段显示了 Apache-based HTTP 客户端和 HTTP 客户端的排除情况。 Netty-based (当你使用客户端时,不需要这些 AWS CRT-based 客户端。) 此示例将 HTTP 客户端构件从 S3 客户端依赖项中排除,并添加了允许访问 AWS CRT-based HTTP 客户端的aws-crt-client对象。
<project> <properties> <aws.java.sdk.version>2.27.21</aws.java.sdk.version> <properties> <dependencyManagement> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>bom</artifactId> <version>${aws.java.sdk.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>aws-crt-client</artifactId> </dependency> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>s3</artifactId> <exclusions> <exclusion> <groupId>software.amazon.awssdk</groupId> <artifactId>netty-nio-client</artifactId> </exclusion> <exclusion> <groupId>software.amazon.awssdk</groupId> <artifactId>apache-client</artifactId> </exclusion> </exclusions> </dependency> </dependencies> </project>
注意
将 <exclusions> 元素添加到 pom.xml 文件中的所有服务客户端依赖项中。
配置服务客户端以进行快捷查找
- 指定区域
-
创建服务客户端时,在服务客户端生成器上调用
region方法。这简化了 SDK 的默认区域查询流程,该过程会检查多个位置 AWS 区域 的信息。要使 Lambda 代码独立于区域,请在
region方法中使用以下代码。此代码访问 Lambda 容器设置的AWS_REGION环境变量。Region.of(System.getenv(SdkSystemSetting.AWS_REGION.environmentVariable())) - 使用
EnvironmentVariableCredentialProvider -
与区域信息的默认查找行为非常相似,SDK 会在多个位置查找凭证。通过在生成服务客户端时指定
EnvironmentVariableCredentialProvider,可以节省 SDK 凭证查找过程的时间。 注意
使用此凭据提供程序可以将代码用于 Lambda 函数,但可能无法在 Amazon EC2 或其他系统上运行。
如果您打算在某个时候使用 SnapStart适用于 Java 的 Lambda,则应依靠默认凭证提供商链来查找证书。如果您指定
EnvironmentVariableCredentialsProvider,则初始凭证查找有效,但激活后 SnapStart ,Java 运行时会设置容器凭据环境变量。激活后,EnvironmentVariableCredentialsProvider使用的环境变量(访问密钥环境变量)对 Java SDK 不可用。
以下代码段显示了为在 Lambda 环境中使用而经过适当配置的 S3 服务客户端。
S3Client s3Client = S3Client.builder() .region(Region.of(System.getenv(SdkSystemSetting.AWS_REGION.environmentVariable()))) .credentialsProvider(EnvironmentVariableCredentialsProvider.create()) .httpClient(AwsCrtHttpClient.builder().build()) .build();
在 Lambda 函数处理程序之外初始化 SDK 客户端
我们建议在 Lambda 处理程序方法之外初始化 SDK 客户端。这样,如果重复使用执行上下文,则可以跳过服务客户端的初始化。通过重复使用客户端实例及其连接,处理程序方法的后续调用可更快进行。
在以下示例中,使用静态工厂方法在构造函数中初始化 S3Client 实例。如果重复使用由 Lambda 环境管理的容器,则会重复使用初始化的 S3Client 实例。
public class App implements RequestHandler<Object, Object> { private final S3Client s3Client; public App() { s3Client = DependencyFactory.s3Client(); } @Override public Object handle Request(final Object input, final Context context) { ListBucketResponse response = s3Client.listBuckets(); // Process the response. } }
尽量减少依赖关系注入
依赖关系注入 (DI) 框架可能需要更多时间才能完成设置过程。它们可能还需要额外的依赖项,这需要一段时间才能加载。
如果需要 DI 框架,建议使用诸如 Dagger
使用 Maven Archetype 进行定位 AWS Lambda
AWS Java 开发工具包团队开发了一个 Maven Archetype
要了解有关原型的更多信息并完成示例部署,请参阅此博客文章
考虑使用 Java 版 Lamb SnapStart da
如果您的运行时要求兼容,则 AWS 提供适用 SnapStart 于 Jav a 的 Lambda。Lambda SnapStart 是一种基于基础设施的解决方案,可提高 Java 函数的启动性能。当您发布新版本的函数时,Lambda 会对其进行 SnapStart 初始化,并拍摄内存和磁盘状态的不可变的加密快照。 SnapStart 然后缓存快照以供重复使用。
要获得启动带来的全部好处 SnapStart,请使用 SdkWarmUp API 在 Lambda 拍摄快照之前预热所有 SDK 客户端。然后,快照会捕获预热的客户端,因此每个恢复的功能都是在准备就绪时开始的。有关更多信息,请参阅 考虑使用以下方法预热 SDK 客户端 SdkWarmUp。
考虑使用以下方法预热 SDK 客户端 SdkWarmUp
中的 SdkWarmUp API会在应用程序初始化期间 AWS SDK for Java 2.x 预热您的SDK客户端。因此,您的第一次服务 API 调用会更快。预热会生成一个客户端,并调用一个操作来执行 SDK 请求路径。这发生在您的应用程序处理实际流量之前。只需一次调用,您就可以预热类路径上的所有 SDK 客户端,或者仅预热应用程序使用的特定客户端。
您可以将 SdkWarmUp API 与可减少冷启动的 Lambda 功能结合使用,例如 Lambda SnapStart 和预置的并发性。有关配置和使用的更多信息SdkWarmUp,请参阅在 SDK 客户端中预热 AWS SDK for Java 2.x。
影响启动时间的 2.x 版更改
除了您对代码所做的更改外,适用于 Java 的 SDK 2.x 版本还包括三项可缩短启动时间的主要更改:
-
使用 jackson-jr
,它是一个序列化库,可以改进初始化时间 -
对日期和时间对象使用 java.time
库,此为 JDK 的一部分。 -
对记录 facade 使用 Slf4j
。
其他资源
AWS Lambda 开发人员指南包含有关开发非 Java 特定的 Lambda 函数的最佳实践的章节。
有关使用的 Java 构建云原生应用程序的示例 AWS Lambda,请参阅此研讨会内容
您可以考虑使用提前编译的静态映像来减少启动延迟。例如,您可以使用适用于 Java 的 SDK 2.x 和 Maven 来构建 GraalVM 原生映像。