AWS Lambda SnapStart Configuration
SnapStart es un mecanismo de snapshot y restauración que reduce drásticamente el tiempo de arranque en frío de las funciones Java en AWS. Este documento explica las distintas configuraciones que puede utilizar para aprovechar esta característica. No es una documentación de referencia sobre SnapStart y no cubrirá en detalle cómo funciona SnapStart.
| 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. |
Activación y desactivación de las optimizaciones de SnapStart
Si utiliza la extensión AWS Lambda de Quarkus, las optimizaciones SnapStart se habilitan automáticamente. Sin embargo, puede habilitarlo/deshabilitarlo explícitamente utilizando:
quarkus.snapstart.enable=true|false
| It does not enable/disable SnapStart for your function, only the Quarkus optimizations. |
Precarga de clases
La carga de clases tiene un gran impacto en el tiempo de ejecución de las funciones. Esta optimización permite precargar clases durante el proceso de instantánea de SnapStart.
Las clases a precargar se enumeran en dos lugares:
-
las extensiones pueden producir una lista de clases (utilizando el elemento de compilación
io.quarkus.deployment.builditem.PreloadClassBuildItem) -
puede añadir un archivo
src/main/resources/META-INF/quarkus-preload-classes.txtque enumere las clases a precargar, por ejemplo:
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
...
El formato es sencillo: una clase por línea.
Cálculo de la lista de clases
| That step is particularly not user-friendly. We plan to improve it. |
Para calcular la lista de clases, recomendamos desplegar su función y establecer la variable de entorno JAVA_TOOL_OPTIONS en -verbose:class. A continuación, ejecute su función y recupere el registro (en CloudWatch). Debería poder extraer los nombres de las clases utilizando sed/awk o cualquier editor de texto.
Lista de clases de aplicaciones
Por defecto, Quarkus genera la lista de clases de las clases incluidas en tu aplicación (incluyendo las clases generadas por Quarkus). Por lo tanto, no tienes que repetirlas en el archivo quarkus-preload-classes.txt.
Puede desactivar esta función mediante:
quarkus.snapstart.generate-application-class-list=false
Preparación del cliente
Preparación del cliente, priming, es una técnica que permite inicializar un cliente durante el proceso de instantánea, de modo que ya es completamente funcional durante el tiempo de ejecución de la aplicación.
Hay dos formas de conseguir priming:
-
inicializar el cliente en un bloque
staticque, gracias a la precarga de clases, se ejecutará antes de la instantánea -
registrar un Recurso CRaC que realice la inicialización
(1) puede lograrse de la siguiente manera:
@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. |
La siguiente sección trata de (2).
Registro de recursos
SnapStart utiliza la API CRaC para permitir que la aplicación ejecute código personalizado antes de la instantánea o durante la restauración.
| 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.
}
}
| Restoration is limited to 2 seconds. |