Reduza o tempo de inicialização do SDK para AWS Lambda - AWS SDK for Java 2.x

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

Reduza o tempo de inicialização do SDK para AWS Lambda

Um dos objetivos do AWS SDK for Java 2.x é reduzir a latência de inicialização AWS Lambda das funções. O SDK contém alterações que reduzem o tempo de inicialização, que são discutidas no final deste tópico.

Primeiro, este tópico se concentra nas mudanças que você pode fazer para reduzir os tempos de inicialização a frio. Isso inclui fazer alterações na estrutura do código e na configuração dos clientes de serviço.

Usar o UrlConnectionHttpClient do SDK

Para cenários síncronos, o SDK for Java 2.x oferece a classe UrlConnectionHttpClient, que se baseia nas classes de cliente HTTP do JDK. Como o UrlConnectionHttpClient é baseado em classes que já estão no caminho de classe, não há dependências extras para carregar.

Para obter informações sobre como adicionar o UrlConnectionHttpClient ao seu projeto Lambda e configurar seu uso, consulte Configurar o cliente HTTP baseado em URLConnection.

nota

Existem algumas limitações de recursos com o UrlConnectionHttpClient em comparação com o ApacheHttpClient do SDK. O ApacheHttpClient é o cliente HTTP assíncrono padrão no SDK. Por exemplo, o UrlConnectionHttpClient não é compatível com o método HTTP PATCH.

Algumas operações de AWS API exigem solicitações de PATCH. Esses nomes de operação geralmente começam com Update*. Veja alguns exemplos a seguir.

Se você puder usar oUrlConnectionHttpClient, primeiro consulte a Referência da API para o AWS service (Serviço da AWS) que você está usando. Verifique se as operações necessárias usam a operação PATCH.

Usar o AwsCrtAsyncHttpClient do SDK

Esse AwsCrtAsyncHttpClient é a contrapartida assíncrona para reduzir o tempo de inicialização do Lambda no SDK.

O AwsCrtAsyncHttpClient é um cliente HTTP assíncrono e sem bloqueio. Ele é construído com base nas ligações Java do AWS Common Runtime, que é escrito na linguagem de programação C. Entre os objetivos no desenvolvimento do AWS Common Runtime está o desempenho rápido.

A seção deste guia sobre a configuração de clientes HTTP tem informações sobre como adicionar um AwsCrtAsyncHttpClient ao seu projeto Lambda e configurar seu uso.

Remover dependências não utilizadas do cliente HTTP

Além do uso explícito de UrlConnectionHttpClient ou AwsCrtAsyncHttpClient, você pode remover outros clientes HTTP que o SDK traz por padrão. O tempo de inicialização do Lambda é reduzido quando menos bibliotecas precisam ser carregadas, então você deve remover quaisquer artefatos não utilizados que a JVM precise carregar.

O seguinte trecho de um arquivo pom.xml do Maven mostra a exclusão do cliente HTTP baseado em Apache e do cliente HTTP baseado em Netty. (Esses clientes não são necessários quando você usa o UrlConnectionHttpClient.) Este exemplo exclui os artefatos do cliente HTTP da dependência do cliente S3 e adiciona o artefato url-connection-client, que traz a classe UrlConnectionHttpClient.

<project> <properties> <aws.java.sdk.version>2.17.290</aws.java.sdk.version> <properties> <dependencyManagement> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>bom</artifactId> <version>${aws.java.sdk.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>url-connection-client</artifactId> </dependency> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>s3</artifactId> <exclusions> <exclusion> <groupId>software.amazon.awssdk</groupId> <artifactId>netty-nio-client</artifactId> </exclusion> <exclusion> <groupId>software.amazon.awssdk</groupId> <artifactId>apache-client</artifactId> </exclusion> </exclusions> </dependency> </dependencies> </project>

Se você usar o AwsCrtAsyncHttpClient, substitua a dependência do url-connection-client por uma dependência do aws-crt-client.

nota

Adicione o elemento <exclusions> a todas as dependências do cliente de serviço em seu arquivo pom.xml.

Configurar clientes de serviço para reduzir as pesquisas

Especificar uma região

Ao criar um cliente de serviço, chame o método region no builder do cliente de serviço. Isso reduz o processo de pesquisa de região padrão do SDK, que verifica as Região da AWS informações em vários locais.

Para manter o código Lambda independente da região, use o código a seguir dentro do método region. Esse código acessa a variável de ambiente AWS_REGION definida pelo contêiner Lambda.

Region.of(System.getenv(SdkSystemSetting.AWS_REGION.environmentVariable()))
Usar a EnvironmentVariableCredentialProvider

Assim como o comportamento padrão de pesquisa das informações da região, o SDK procura credenciais em vários lugares. Ao especificar o EnvironmentVariableCredentialProvider quando você cria um cliente de serviço, você economiza tempo no processo de pesquisa do SDK.

nota

O uso desse provedor de credenciais permite que o código seja usado em Lambda funções, mas pode não funcionar em Amazon EC2 ou em outros sistemas.

O trecho de código a seguir mostra um cliente de serviço do S3 configurado adequadamente para uso em um ambiente Lambda.

S3Client client = S3Client.builder() .region(Region.of(System.getenv(SdkSystemSetting.AWS_REGION.environmentVariable()))) .credentialsProvider(EnvironmentVariableCredentialsProvider.create()) .httpClient(UrlConnectionHttpClient.builder().build()) .build();

Inicializar o cliente SDK fora do manipulador da função do Lambda

Recomendamos inicializar um cliente SDK fora do método manipulador do Lambda. Dessa forma, se o contexto de execução for reutilizado, a inicialização do cliente de serviço poderá ser ignorada. Ao reutilizar a instância do cliente e suas conexões, as invocações subsequentes do método manipulador ocorrem mais rapidamente.

No exemplo a seguir, a instância S3Client é inicializada no construtor usando um método estático de fábrica. Se o contêiner gerenciado pelo ambiente Lambda for reutilizado, a instância S3Client inicializada será reutilizada.

public class App implements RequestHandler<Object, Object> { private final S3Client s3Client; public App() { s3Client = DependencyFactory.s3Client(); } @Override public Object handle Request(final Object input, final Context context) { ListBucketResponse response = s3Client.listBuckets(); // Process the response. } }

Minimize a injeção de dependência

As estruturas de injeção de dependência (DI) podem levar mais tempo para concluir o processo de configuração. Elas também podem exigir dependências adicionais, que levam tempo para serem carregadas.

Se uma estrutura de DI for necessária, recomendamos o uso de estruturas de DI leves, como o Dagger.

Use uma mira do Maven Archetype AWS Lambda

A equipe do AWS Java SDK desenvolveu um modelo Maven Archetype para iniciar um projeto Lambda com o mínimo de tempo de inicialização. Você pode criar um projeto Maven a partir do arquétipo e saber se as dependências estão configuradas adequadamente para o ambiente Lambda.

Para saber mais sobre o arquétipo e trabalhar com um exemplo de implantação, consulte esta postagem no blog.

Considere o Lambda SnapStart para Java

Se seus requisitos de tempo de execução forem compatíveis, AWS oferece o Lambda SnapStart para Java. O Lambda SnapStart é uma solução baseada em infraestrutura que melhora o desempenho de inicialização das funções Java. Quando você publica uma nova versão de uma função, o Lambda a SnapStart inicializa e tira um instantâneo imutável e criptografado da memória e do estado do disco. SnapStart em seguida, armazena o instantâneo em cache para reutilização.

Alterações na versão 2.x que afetam o tempo de inicialização

Além das alterações que você faz no seu código, a versão 2.x do SDK para Java inclui três alterações principais que reduzem o tempo de inicialização:

  • Uso de jackson-jr, que é uma biblioteca de serialização que melhora o tempo de inicialização

  • Uso das bibliotecas java.time para objetos de data e hora, que faz parte do JDK

  • Uso de Slf4j para uma fachada de registro em log

Recursos adicionais do

O Guia do AWS Lambda desenvolvedor contém uma seção sobre as melhores práticas para o desenvolvimento de funções Lambda que não são específicas de Java.

Para ver um exemplo de criação de um aplicativo nativo da nuvem em Java que usa AWS Lambda, consulte o conteúdo deste workshop. O workshop discute a otimização do desempenho e outras práticas recomendadas.

Você pode considerar o uso de imagens estáticas que são compiladas com antecedência para reduzir a latência de inicialização. Por exemplo, você pode usar o SDK for Java 2.x e o Maven para criar uma imagem nativa do GraalVM.