The English version of quarkus.io is the official project site. Translated sites are community supported on a best-effort basis.
Edit this Page

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:

  1. las extensiones pueden producir una lista de clases (utilizando el elemento de compilación io.quarkus.deployment.builditem.PreloadClassBuildItem)

  2. 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

Desactivar la precarga

Puede desactivar la precarga de clases utilizando:

quarkus.snapstart.preload-classes=false

Omitir la inicialización de clases

Por defecto, cuando se precargan las clases, también se inicializan, lo que significa que también resuelve las clases dependientes. Puede desactivar este comportamiento utilizando:

quarkus.snapstart.initialize-classes=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:

  1. inicializar el cliente en un bloque static que, gracias a la precarga de clases, se ejecutará antes de la instantánea

  2. 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.

Compilación por niveles

También se recomienda utilizar la compilación por niveles al utilizar SnapStart. Para ello, establezca la propiedad de entorno JAVA_TOOL_OPTIONS en -XX:+TieredCompilation -XX:TieredStopAtLevel=1.

TieredCompilation también puede ser interesante para funciones Lambda normales.

Related content