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

Configuração do AWS Lambda 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.

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.

Ativar / Desativar as otimizações do 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
Isso não ativa/desactiva o SnapStart para a sua função, apenas as otimizações do Quarkus.

Pré-carregamento de classes

Classloading has a huge impact on your function execution time. This optimization allows preloading classes during the snapshotting process of SnapStart.

As classes que serão pré-carregadas estão listadas em dois lugares:

  1. as extensões podem produzir uma lista de classes (utilizando o item de compilação io.quarkus.deployment.builditem.PreloadClassBuildItem )

  2. você pode adicionar um arquivo src/main/resources/META-INF/quarkus-preload-classes.txt que enumere as classes que serão pré-carregadas, como por exemplo:

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

O formato é simples: uma classe por linha.

Calculando a lista de classes

Esta etapa é particularmente não é tão fácil de usar. Iremos melhorar este processo em um futuro próximo.

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.

Lista de classes da aplicação

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.

Você pode desativar esta funcionalidade utilizando:

quarkus.snapstart.generate-application-class-list=false

Desativar o pré-carregamento

Você pode desativar o pré-carregamento de classes utilizando:

quarkus.snapstart.preload-classes=false

Pulando a inicialização da classe

By default, when the classes are preloaded, they are also initialized, meaning it also resolves the dependent classes. You can disable this behavior using:

quarkus.snapstart.initialize-classes=false

Preparando o client

Client priming é uma técnica que permite inicializar um client durante o processo de snapshotting, para que já esteja totalmente funcional durante o tempo de execução da aplicação.

Existem duas formas de obter priming:

  1. inicializar o client num bloco static, que, graças ao pré-carregamento da classe, será executado antes do snapshot

  2. registar um recurso CRaC que efetua a inicialização

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

A próxima seção aborda o tópico(2).

Registo de recursos

O SnapStart utiliza a API CRaC para permitir que a aplicação execute código personalizado antes do snapshotting ou durante a restauração.

Embora seja a API CRaC, o SnapStart não é CRaC e pode fazer coisas que não funcionariam com outras implementações 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.
    }
}
A restauração é limitada a 2 segundos.

Compilação em camadas

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 também pode ser interessante para funções Lambda regulares.

Conteúdo Relacionado