本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
缩短SDK启动时间 Amazon Lambda
的目标之一 Amazon SDK for Java 2.x 是减少 Amazon Lambda 函数的启动延迟。SDK包含缩短启动时间的更改,本主题末尾将对此进行讨论。
首先,本主题重点介绍为缩短冷启动时间可以进行的更改。这包括更改代码结构和服务客户端的配置。
使用 Amazon CRT基于基础的HTTP客户端
对于使用 Amazon Lambda,我们建议在同步场景中使用,AwsCrtHttpClient
AwsCrtAsyncHttpClient
本指南中的Amazon CRT基于配置的HTTP客户端主题描述了使用HTTP客户端的好处、如何添加依赖关系以及如何配置服务客户端对它们的使用。
移除未使用的HTTP客户端依赖关系
除了显式使用 Amazon CRT基于客户端的外,您还可以移除默认情况下SDK引入的其他HTTP客户端。当需要加载的库较少时,Lambda 的启动时间会缩短,因此您应该删除JVM需要加载的所有未使用的工件。
以下 Maven pom.xml
文件片段显示了基于 Apache 的客户端和基于 Netty 的HTTP客户端的排除情况。HTTP(当您使用 Amazon CRT基于基础的客户端时,不需要这些客户端。) 此示例将HTTP客户端对象排除在 S3 客户端依赖项之外,并添加了该aws-crt-client
对象以允许访问 Amazon CRT基于这些HTTP客户端的客户端。
<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的区域查找过程,该过程会在多个位置检查 Amazon Web Services 区域 信息。要使 Lambda 代码独立于区域,请在
region
方法中使用以下代码。此代码访问 Lambda 容器设置的AWS_REGION
环境变量。Region.of(System.getenv(SdkSystemSetting.AWS_REGION.environmentVariable()))
- 使用
EnvironmentVariableCredentialProvider
-
就像区域信息的默认查找行为一样,会在SDK多个位置查找证书。通过指定
EnvironmentVariableCredentialProvider
何时构建服务客户端,可以节省证书查找过程中的时间。SDK 注意
使用此凭证提供程序可以将代码用于 Lambda 函数,但可能无法在 Amazon EC2 或其他系统上运行。
如果您打算在某个时候使用 Lambd SnapStart a for Java,则应依靠默认的凭证提供程序链来查找证书。如果您指定
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 瞄准 Amazon Lambda
Amazon Java SDK 团队开发了一个 Maven Archetype
要了解有关原型的更多信息并完成示例部署,请参阅此博客文章
考虑一下适用于 Java 的 Lambda SnapStart
如果您的运行时要求兼容,则 Amazon 提供适用 SnapStart 于 Java 的 Lambda。Lambda SnapStart 是一种基于基础设施的解决方案,可提高 Java 函数的启动性能。当您发布新版本的函数时,Lambda 会对其进行 SnapStart 初始化,并拍摄内存和磁盘状态的不可变加密快照。 SnapStart 然后缓存快照以供重复使用。
影响启动时间的 2.x 版更改
除了您对代码所做的更改外,SDK适用于 Java 的 2.x 版本还包括三项主要更改,可缩短启动时间:
-
使用 jackson-jr
,它是一个序列化库,可以改进初始化时间 -
将 java.tim
e 库用于日期和时间对象,这是其中的一部分 JDK -
对记录 facade 使用 Slf4j
。
其他 资源
Amazon Lambda 开发者指南中有一节介绍开发非 Java 特定的 Lambda 函数的最佳实践。
有关使用 Java 构建云原生应用程序的示例 Amazon Lambda,请参阅此研讨会内容
您可以考虑使用提前编译的静态映像来减少启动延迟。例如,你可以使用适用于 Java 2.x 和 Maven 的 GraalVM 原生镜像。SDK