AWS Lambda SnapStart Configuration
SnapStart 是一种快照和恢复机制,能够显著降低 AWS 上 Java 函数的冷启动时间。本文档说明了您可以使用此功能的各种设置。它并非 SnapStart 的参考文档,不会详细介绍 SnapStart 的工作原理。
SnapStart is a snapshotting and restore mechanism reducing drastically the cold startup time of Java functions on AWS. This document explains the various settings you can use to leverage this feature. It is not a reference documentation on SnapStart, and it will not cover how SnapStart works in details.
此功能仅适用于 AWS Lambda,且无法在所有区域内使用。请查阅 AWS 文档以验证您的 AWS 区域是否符合条件。
This feature is only available on AWS Lambda, and not in all regions. Please check the AWS documentation to verify the eligibility of your AWS region.
Enabling / Disabling SnapStart Optimizations
如果您使用 Quarkus AWS Lambda 扩展,SnapStart 优化将自动启用。但是,您可以使用以下命令明确启用/禁用它:
If you use the Quarkus AWS Lambda extension, SnapStart optimizations are automatically enabled. However, you can enable/disable it explicitly using:
quarkus.snapstart.enable=true|false
这不会为您的函数启用/禁用 SnapStart,只会启用/禁用 Quarkus 优化。
It does not enable/disable SnapStart for your function, only the Quarkus optimizations.
Class Preloading
类加载会对函数执行时间产生重大影响。此优化功能允许在 SnapStart 的快照处理过程中预加载类。
Classloading has a huge impact on your function execution time. This optimization allows preloading classes during the snapshotting process of SnapStart.
需要预加载的类在两个位置列出:
The classes to preload are listed in two places:
-
extensions can produce a list of classes (using the
io.quarkus.deployment.builditem.PreloadClassBuildItem
build item) -
you can add a
src/main/resources/META-INF/quarkus-preload-classes.txt
file listing the classes to preload, such as:
com.amazonaws.services.lambda.runtime.LambdaRuntimeInternal
com.fasterxml.jackson.annotation.JsonAlias
com.fasterxml.jackson.annotation.JsonFormat$Feature
com.fasterxml.jackson.core.exc.InputCoercionException
com.fasterxml.jackson.core.exc.StreamWriteException
com.fasterxml.jackson.core.io.ContentReference
com.fasterxml.jackson.core.io.IOContext
com.fasterxml.jackson.core.io.JsonEOFException
com.fasterxml.jackson.core.io.MergedStream
com.fasterxml.jackson.core.io.NumberInput
com.fasterxml.jackson.core.io.NumberOutput
com.fasterxml.jackson.core.io.UTF32Reader
com.fasterxml.jackson.core.json.ByteSourceJsonBootstrapper
com.fasterxml.jackson.core.json.JsonReadContext
com.fasterxml.jackson.core.json.JsonWriteContext
com.fasterxml.jackson.core.json.UTF8StreamJsonParser
com.fasterxml.jackson.core.JsonEncoding
com.fasterxml.jackson.core.JsonGenerationException
com.fasterxml.jackson.core.JsonLocation
com.fasterxml.jackson.core.JsonStreamContext
com.fasterxml.jackson.core.JsonToken
...
格式很简单:每行一个类。
The format is simple: one class per line.
Computing the class list
此步骤不友好。我们计划对此进行改进。 |
That step is particularly not user-friendly. We plan to improve it. |
为了计算类列表,我们建议您部署函数并设置 JAVA_TOOL_OPTIONS
环境变量为 -verbose:class
。然后执行函数并检索日志(在 CloudWatch 中)。您应该能够使用 sed/awk 或任何文本编辑器提取类名称。
To compute the list of classes, we recommend deploying your function and setting the JAVA_TOOL_OPTIONS
environment variable to -verbose:class
.
Then execute your function and retrieve the log (in CloudWatch).
You should be able to extract the class names using sed/awk or any text editor.
Application class list
默认情况下,Quarkus 会生成应用程序中包含类列表(包括由 Quarkus 生成的类)。因此,您不必在 quarkus-preload-classes.txt
文件中重复它们。
By default, Quarkus generates the class list of the classes included in your application (including the classes generated by Quarkus).
So, you do not have to repeat them in the quarkus-preload-classes.txt
file.
您可以使用以下步骤禁用此功能:
You can disable this feature using:
quarkus.snapstart.generate-application-class-list=false
Client Priming
客户端 _priming_是一种技术,允许在快照过程中初始化客户端,这样在应用程序运行时,该客户端已经完全具有功能。
Client priming is a technique that allows initializing a client during the snapshotting process, so it’s already fully functional during the application runtime.
有两种方式实现 priming:
There are two ways to achieve priming:
-
initialize the client in a
static
block, which, thanks to class preloading will be executed before the snapshot -
register a CRaC Resource doing the initialization
(1) 可以通过以下方式实现:
(1) can be achieved as follows:
@ApplicationScoped
public class HeroRepository {
private static final DynamoDbClient client;
static {
client = DynamoDbClient.builder()
.region(Region.US_EAST_2)
.credentialsProvider(DefaultCredentialsProvider.create())
.build();
client.describeEndpoints();
}
// ...
}
使用静态块实现预处理可能阻止你的应用程序的本机编译。客户端初始化可能会启动线程或打开连接,如果该类在构建时初始化,则这些行为与本机编译不兼容。
Implementing priming using a static block may prevent the native compilation of your application. Client initialization may start threads or open connections which are not compatible with the native compilation if the class is initialized at build time.
下一部分涵盖 (2)。
The next section covers (2).
Resource registration
SnapStart 使用 CRaC API 允许应用程序在快照之前或还原期间执行自定义代码。
SnapStart uses the CRaC API to allow the application to execute custom code before the snapshotting or during the restoration.
虽然它是 CRaC API,但 SnapStart 并不是 CRaC,并且可以执行 things,而其他 CRaC 实现则不会。
While it’s the CRaC API, SnapStart is not CRaC and can do things that would not work with others CRaC implementations.
package org.acme.hello;
import io.quarkus.runtime.Startup;
import org.crac.Context;
import org.crac.Core;
import org.crac.Resource;
import org.jboss.logging.Logger;
import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
@Startup
@ApplicationScoped
public class HelloPriming implements Resource {
@Inject
Logger logger;
@PostConstruct
void init() {
// Important - register the resource
Core.getGlobalContext().register(this);
}
@Override
public void beforeCheckpoint(Context<? extends Resource> context) throws Exception {
logger.info("before checkout hook");
// initialize your client here.
}
@Override
public void afterRestore(Context<? extends Resource> context) throws Exception {
logger.info("after checkout hook");
// if there is anything to do during the restoration, do it here.
}
}
还原时间限制为 2 秒。
Restoration is limited to 2 seconds.
TieredCompilation
当使用 SnapStart 时,还建议使用 tiered compilation。要实现这一点,将 JAVA_TOOL_OPTIONS`环境属性设为 `-XX:+TieredCompilation -XX:TieredStopAtLevel=1
。
It is also recommended to use tiered compilation when using SnapStart.
To achieve this, set the JAVA_TOOL_OPTIONS
environment property to -XX:+TieredCompilation -XX:TieredStopAtLevel=1
.
`TieredCompilation`对于普通 Lambda 函数也可能很有用。 |
|