Implantar funções do Lambda em Java com arquivos .zip ou JAR - AWS Lambda

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

Implantar funções do Lambda em Java com arquivos .zip ou JAR

O código da função do AWS Lambda consiste em scripts ou programas compilados e as dependências deles. Você usa umpacote de implantaçãopara implantar seu código de função no Lambda. O Lambda é compatível com dois tipos de pacotes de implantação: imagens de contêiner e arquivos .zip.

Esta página descreve como criar o seu pacote de implantação como um arquivo .zip ou Jar e, em seguida, usar o pacote para implantar o seu código de função para o AWS Lambda usando a AWS Command Line Interface (AWS CLI).

Pré-requisitos

O AWS CLI é uma ferramenta de código aberto que permite interagir com os serviços do AWS usando comandos no shell da linha de comando. Para executar as etapas desta seção, você deve ter o seguinte:

Ferramentas e bibliotecas

O Lambda fornece as seguintes bibliotecas para funções em Java:

Essas bibliotecas estão disponíveis no repositório central do Maven. Adicione-as à sua definição de compilação da seguinte forma:

Gradle
dependencies { implementation 'com.amazonaws:aws-lambda-java-core:1.2.2' implementation 'com.amazonaws:aws-lambda-java-events:3.11.1' runtimeOnly 'com.amazonaws:aws-lambda-java-log4j2:1.5.1' }
Maven
<dependencies> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-core</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-events</artifactId> <version>3.11.1</version> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-log4j2</artifactId> <version>1.5.1</version> </dependency> </dependencies>

Para criar um pacote de implantação, compile o código e as dependências da sua função em um único arquivo .zip ou Java Archive (JAR). Para o Gradle, use o tipo de compilação Zip. Para o Apache Maven, use o plugin Maven Shade. Para fazer o upload do seu pacote de implantação, use o console do Lambda, a API do Lambda ou o AWS Serverless Application Model (AWS SAM).

nota

Para manter o pacote de implantação pequeno, empacote as dependências da função em camadas. As camadas permitem gerenciar as suas dependências de forma independente, podem ser usadas por várias funções e podem ser compartilhadas com outras contas. Para ter mais informações, consulte Trabalhar com camadas do Lambda.

Compilar um pacote de implantação com o Gradle

Para criar um pacote de implantação com o código e as dependências da sua função no Gradle, use o tipo de compilação Zip. Aqui está um exemplo de um arquivo build.gradle completo de amostra:

exemplo build.gradle: tarefa de compilação
task buildZip(type: Zip) { into('lib') { from(jar) from(configurations.runtimeClasspath) } }

Essa configuração de compilação produz um pacote de implantação no diretório build/distributions. Na instrução into('lib'), a tarefa jar monta um arquivo jar contendo suas classes principais em uma pasta denominada lib. Além disso, a tarefa configurations.runtimeClassPath copia bibliotecas de dependência do caminho de classe da compilação para a mesma pasta lib.

exemplo build.gradle: dependências
dependencies { ... implementation 'com.amazonaws:aws-lambda-java-core:1.2.2' implementation 'com.amazonaws:aws-lambda-java-events:3.11.1' implementation 'org.apache.logging.log4j:log4j-api:2.17.1' implementation 'org.apache.logging.log4j:log4j-core:2.17.1' runtimeOnly 'org.apache.logging.log4j:log4j-slf4j18-impl:2.17.1' runtimeOnly 'com.amazonaws:aws-lambda-java-log4j2:1.5.1' ... }

O Lambda carrega arquivos JAR em Unicode em ordem alfabética. Se vários arquivos JAR no diretório lib contiverem a mesma classe, a primeira será usada. Use o script de shell a seguir para identificar classes duplicadas.

exemplo test-zip.sh
mkdir -p expanded unzip path/to/my/function.zip -d expanded find ./expanded/lib -name '*.jar' | xargs -n1 zipinfo -1 | grep '.*.class' | sort | uniq -c | sort

Criar uma camada Java para suas dependências

nota

Usar camadas com funções em uma linguagem compilada, como Java, pode não oferecer o mesmo benefício que com uma linguagem interpretada, como Python. Como Java é uma linguagem compilada, suas funções ainda precisam carregar manualmente quaisquer montagens compartilhadas na memória durante a fase inicial, o que pode aumentar os tempos de inicialização a frio. Em vez disso, recomendamos incluir qualquer código compartilhado no momento da compilação para aproveitar as otimizações integradas do compilador.

As instruções nesta seção mostram como incluir suas dependências em uma camada. Para obter instruções sobre como incluir suas dependências em seu pacote de implantação, consulte Compilar um pacote de implantação com o Gradle ou Compilar um pacote de implantação com o Maven.

Quando você adiciona uma camada a uma função, o Lambda carrega o conteúdo da camada no diretório /opt desse ambiente de execução. Para cada runtime do Lambda, a variável PATH já inclui caminhos de pasta específica no diretório /opt. Para garantir que o conteúdo da sua camada seja captado pela variável PATH, inclua o conteúdo nos seguintes caminhos da pasta:

  • java/lib (CLASSPATH)

Por exemplo, sua estrutura de arquivo .zip da sua camada pode ser assim:

jackson.zip └ java/lib/jackson-core-2.2.3.jar

Além disso, o Lambda detecta automaticamente todas as bibliotecas no diretório /opt/lib e quaisquer binários no diretório /opt/bin. Para garantir que o Lambda encontre corretamente o conteúdo da sua camada, você também pode criar uma camada com a seguinte estrutura:

custom-layer.zip └ lib | lib_1 | lib_2 └ bin | bin_1 | bin_2

Depois de empacotar sua camada, consulte Criar e excluir camadas no Lambda e Adicionar camadas às funções para concluir sua configuração de camada.

Compilar um pacote de implantação com o Maven

Para compilar um pacote de implantação com o Maven, use o plugin Maven Shade. O plugin cria um arquivo JAR que contém o código de função compilado e todas as suas dependências.

exemplo pom.xml: configuração do plugin
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.2</version> <configuration> <createDependencyReducedPom>false</createDependencyReducedPom> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> </execution> </executions> </plugin>

Para compilar o pacote de implantação, use o comando mvn package.

[INFO] Scanning for projects... [INFO] -----------------------< com.example:java-maven >----------------------- [INFO] Building java-maven-function 1.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- ... [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ java-maven --- [INFO] Building jar: target/java-maven-1.0-SNAPSHOT.jar [INFO] [INFO] --- maven-shade-plugin:3.2.2:shade (default) @ java-maven --- [INFO] Including com.amazonaws:aws-lambda-java-core:jar:1.2.2 in the shaded jar. [INFO] Including com.amazonaws:aws-lambda-java-events:jar:3.11.1 in the shaded jar. [INFO] Including joda-time:joda-time:jar:2.6 in the shaded jar. [INFO] Including com.google.code.gson:gson:jar:2.8.6 in the shaded jar. [INFO] Replacing original artifact with shaded artifact. [INFO] Replacing target/java-maven-1.0-SNAPSHOT.jar with target/java-maven-1.0-SNAPSHOT-shaded.jar [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 8.321 s [INFO] Finished at: 2020-03-03T09:07:19Z [INFO] ------------------------------------------------------------------------

Esse comando gera um arquivo JAR no diretório target.

nota

Se você estiver trabalhando com um JAR de várias versões (MRJAR), é necessário incluir o MRJAR (ou seja, o JAR sombreado produzido pelo plugin Maven Shade) no diretório lib e compactá-lo antes de fazer upload do seu pacote de implantação para o Lambda. Caso contrário, o Lambda pode não descompactar adequadamente seu arquivo JAR, fazendo com que seu arquivo MANIFEST.MF seja ignorado.

Se você usar a biblioteca appender (aws-lambda-java-log4j2), também será necessário configurar um transformador para o plugin Maven Shade. A biblioteca do transformador combina versões de um arquivo de cache que aparecem na biblioteca appender e no Log4j.

exemplo pom.xml: configuração do plugin com o appender do Log4j 2
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.2</version> <configuration> <createDependencyReducedPom>false</createDependencyReducedPom> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="com.github.edwgiz.maven_shade_plugin.log4j2_cache_transformer.PluginsCacheFileTransformer"> </transformer> </transformers> </configuration> </execution> </executions> <dependencies> <dependency> <groupId>com.github.edwgiz</groupId> <artifactId>maven-shade-plugin.log4j2-cachefile-transformer</artifactId> <version>2.13.0</version> </dependency> </dependencies> </plugin>

Upload de um pacote de implantação com o console do Lambda

Para criar uma nova função, você deve primeiro criar a função no console e depois carregar o arquivo .zip ou JAR. Para atualizar uma função existente, abra a página da função e siga o mesmo procedimento para adicionar o arquivo .zip ou JAR atualizado.

Se o arquivo do pacote de implantação for menor que 50 MB, você poderá criar ou atualizar uma função carregando o arquivo diretamente da máquina local. Para arquivos .zip ou JAR maiores que 50 MB, você deve primeiro carregar o pacote para um bucket do Amazon S3. Para obter instruções sobre como carregar um arquivo para um bucket do Amazon S3 usando o AWS Management Console, consulte Conceitos básicos do Amazon S3. Para carregar arquivos usando a AWS CLI, consulte Mover objetos no Guia do usuário da AWS CLI.

nota

Você não pode alterar o tipo de pacote de implantação (.zip ou imagem de contêiner) de uma função existente. Por exemplo, você não pode converter uma função de imagem de contêiner para usar um arquivo compactado. zip. É necessário criar uma nova função.

Para criar uma função (console)
  1. Abra a página Funções do console do Lambda e escolha Criar função.

  2. Escolha Author from scratch (Criar do zero).

  3. Em Basic information (Informações básicas), faça o seguinte:

    1. Em Nome da função, insira o nome da função.

    2. Em Runtime, selecione o runtime que você deseja usar.

    3. (Opcional) Em Arquitetura, escolha a arquitetura do conjunto de instruções para a função. O valor da arquitetura padrão é X86_64. Certifique-se de que o pacote de implantação .zip da função seja compatível com a arquitetura do conjunto de instruções que você escolheu.

  4. (Opcional) Em Permissões, expanda Alterar função de execução padrão. Crie uma função de execução ou use uma existente.

  5. Escolha a opção Criar função. O Lambda cria uma função básica “Hello world” usando o runtime escolhido.

Para carregar o arquivo .zip ou JAR da máquina local (console)
  1. Na página Funções do console Lambda, escolha a função para a qual você deseja carregar o arquivo .zip ou JAR.

  2. Selecione a guia Código.

  3. No painel do Código-fonte, escolha Carregar de.

  4. Escolha o arquivo .zip ou .jar.

  5. Para carregar o arquivo .zip ou JAR, faça o seguinte:

    1. Selecione Carregar e, em seguida, selecione o arquivo .zip ou JAR no seletor de arquivos.

    2. Escolha Open (Abrir).

    3. Escolha Salvar.

Para carregar um arquivo .zip ou JAR de um bucket do Amazon S3 (console)
  1. Na página Funções do console do Lambda, escolha a função para a qual você deseja carregar um novo arquivo .zip ou JAR.

  2. Selecione a guia Código.

  3. No painel do Código-fonte, escolha Carregar de.

  4. Escolha Local do Amazon S3.

  5. Cole o URL do link do Amazon S3 do arquivo .zip e escolha Salvar.

Carregar um pacote de implantação com a AWS CLI

Você pode usar a AWS CLI para criar uma função ou atualizar uma existente usando um arquivo .zip ou JAR. Use a função de criação e os update-function-codecomandos para implantar seu pacote .zip ou JAR. Se o arquivo for menor que 50 MB, você poderá carregar o pacote de um local do arquivo na máquina de compilação local. Para arquivos maiores, você deve carregar o pacote .zip ou JAR de um bucket do Amazon S3. Para obter instruções sobre como carregar um arquivo para um bucket do Amazon S3 usando a AWS CLI, consulte Mover objetos no Guia do usuário da AWS CLI.

nota

Se você carregar o arquivo .zip ou JAR de um bucket do Amazon S3 usando a AWS CLI, o bucket deverá estar na mesma Região da AWS que sua função.

Para criar uma função usando um arquivo .zip ou JAR com a AWS CLI, você deve especificar o seguinte:

  • O nome da função (--function-name)

  • O runtime da função (--runtime)

  • O nome do recurso da Amazon (ARN) da função de execução da função (--role)

  • O nome do método do manipulador no código da função (--handler)

Você também deve especificar a local do arquivo .zip ou JAR. Se o arquivo .zip ou JAR estiver localizado em uma pasta da máquina de compilação local, use a opção --zip-file para especificar o caminho do arquivo, conforme mostrado no comando do exemplo a seguir.

aws lambda create-function --function-name myFunction \ --runtime java21 --handler example.handler \ --role arn:aws:iam::123456789012:role/service-role/my-lambda-role \ --zip-file fileb://myFunction.zip

Para especificar o local do arquivo .zip em um bucket do Amazon S3, use a opção --code conforme mostrado no comando do exemplo a seguir. Você só precisa usar o parâmetro S3ObjectVersion para objetos com versionamento.

aws lambda create-function --function-name myFunction \ --runtime java21 --handler example.handler \ --role arn:aws:iam::123456789012:role/service-role/my-lambda-role \ --code S3Bucket=myBucketName,S3Key=myFileName.zip,S3ObjectVersion=myObjectVersion

Para atualizar uma função existente usando a CLI, especifique o nome da função usando o parâmetro --function-name. Você também deve especificar o local do arquivo .zip que deseja usar para atualizar o código da função. Se o arquivo .zip estiver localizado em uma pasta da máquina de compilação local, use a opção --zip-file para especificar o caminho do arquivo, conforme mostrado no comando do exemplo a seguir.

aws lambda update-function-code --function-name myFunction \ --zip-file fileb://myFunction.zip

Para especificar o local do arquivo .zip em um bucket do Amazon S3, use as opções --s3-bucket e --s3-key conforme mostrado no comando do exemplo a seguir. Você só precisa usar o parâmetro --s3-object-version para objetos com versionamento.

aws lambda update-function-code --function-name myFunction \ --s3-bucket myBucketName --s3-key myFileName.zip --s3-object-version myObject Version

Fazer upload de um pacote de implantação com o AWS SAM

É possível usar o AWS SAM para automatizar implantações do código, da configuração e das dependências da sua função. O AWS SAM é uma extensão do AWS CloudFormation que fornece uma sintaxe simplificada para definir aplicações sem servidor. O seguinte exemplo de modelo define uma função com um pacote de implantação no diretório build/distributions que o Gradle usa:

exemplo template.yml
AWSTemplateFormatVersion: '2010-09-09' Transform: 'AWS::Serverless-2016-10-31' Description: An AWS Lambda application that calls the Lambda API. Resources: function: Type: AWS::Serverless::Function Properties: CodeUri: build/distributions/java-basic.zip Handler: example.Handler Runtime: java21 Description: Java function MemorySize: 512 Timeout: 10 # Function's execution role Policies: - AWSLambdaBasicExecutionRole - AWSLambda_ReadOnlyAccess - AWSXrayWriteOnlyAccess - AWSLambdaVPCAccessExecutionRole Tracing: Active

Para criar a função, use os comandos deploy e package. Esses comandos são personalizações para a AWS CLI. Eles envolvem outros comandos para fazer upload do pacote de implantação no Amazon S3, reescrevem o modelo com o URI do objeto e atualizam o código da função.

O exemplo de script a seguir executa uma compilação do Gradle e faz upload do pacote de implantação que ele cria. Ele cria uma pilha do AWS CloudFormation na primeira vez que você executá-lo. Se a pilha já existir, o script a atualizará.

exemplo deploy.sh
#!/bin/bash set -eo pipefail aws cloudformation package --template-file template.yml --s3-bucket MY_BUCKET --output-template-file out.yml aws cloudformation deploy --template-file out.yml --stack-name java-basic --capabilities CAPABILITY_NAMED_IAM

Para obter um modelo funcional completo, consulte as seguintes aplicações de exemplo:

Aplicações de exemplo do Lambda em Java
  • java17-examples: uma função em Java que demonstra como usar um registro Java para representar um objeto de dados de evento de entrada.

  • java-basic: uma coleção de funções Java mínimas com testes de unidade e configuração de registro em log variável.

  • java-events: uma coleção de funções do Java contendo código básico sobre como lidar com eventos de vários serviços, como o Amazon API Gateway, o Amazon SQS e o Amazon Kinesis. Essas funções usam a versão mais recente da aws-lambda-java-eventsbiblioteca (3.0.0 e mais recente). Estes exemplos não exigem oAWS SDK como dependência.

  • s3-java: uma função em Java que processa eventos de notificação do Amazon S3 e usa a Java Class Library (JCL) para criar miniaturas de arquivos de imagem enviados por upload.

  • Use API Gateway to invoke a Lambda function (Usar o API Gateway para invocar uma função do Lambda): uma função Java que verifica uma tabela do Amazon DynamoDB contendo informações de funcionários. Em seguida, usa o Amazon Simple Notification Service para enviar uma mensagem de texto aos funcionários comemorando seus aniversários de empresa. Este exemplo usa o API Gateway para invocar a função.