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.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
| 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
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(); } // ... } | 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. |