Configuración de AWS Lambda SnapStart
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.
Esta característica solo está disponible en AWS Lambda y no en todas las regiones. Consulte la documentación de AWS para verificar la elegibilidad de su región de AWS. |
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
No activa/desactiva SnapStart para su función, sólo las optimizaciones de Quarkus. |
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.txt
que 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
Ese paso no es especialmente fácil de usar. Tenemos previsto mejorarlo. |
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
static
que, 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();
}
// ...
}
Implementar priming utilizando un bloque estático puede impedir la compilación nativa de tu aplicación. La inicialización del cliente puede iniciar hilos o abrir conexiones que no son compatibles con la compilación nativa si la clase se inicializa en tiempo de compilación. |
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.
Aunque es la API de CRaC, SnapStart no es CRaC y puede hacer cosas que no funcionarían con otras implementaciones de CRaC. |
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.
}
}
La restauración está limitada a 2 segundos. |