Implementar funciones de Lambda Java con archivos de archivo .zip o JAR - AWS Lambda

Implementar funciones de Lambda Java con archivos de archivo .zip o JAR

El código de la función AWS Lambda se compone de scripts o programas compilados y sus dependencias. Utiliza un paquete de implementación para implementar su código de función en Lambda. Lambda admite dos tipos de paquetes de implementación: imágenes de contenedor y archivos .zip.

Esta página describe cómo crear un archivo.zip o archivo Jar en su paquete de implementación y luego usar el archivo para implementar el código de función a AWS Lambda con el AWS Command Line Interface (AWS CLI).

Prerequisites

La AWS CLI es una herramienta de código abierto que le permite interactuar con los servicios de AWS mediante el uso de comandos en el shell de la línea de comandos. Para completar los pasos en esta sección, debe disponer de lo siguiente:

Herramientas y bibliotecas

Lambda proporciona las siguientes bibliotecas de funciones de Java:

Estas bibliotecas están disponibles en el repositorio central de Maven. Agréguelas a la definición de la compilación de la siguiente manera:

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

Para crear un paquete de implementación, compile el código de función y las dependencias en un único archivo .zip o Java Archive (JAR). En el caso de Gradle, use el tipo de compilación Zip. En el caso de Apache Maven, use el complemento Maven Shade.

nota

Para que el tamaño del paquete de implementación sea reducido, empaquete las dependencias de la función en capas. Las capas le permiten administrar las dependencias de forma independiente, pueden utilizarlas varias funciones y pueden compartirse con otras cuentas. Para obtener más información, consulte Creación y uso compartido de capas de Lambda.

Puede cargar el paquete de implementación a través de la consola de Lambda, la API de Lambda o AWS Serverless Application Model (AWS SAM).

Para cargar un paquete de implementación con la consola de Lambda

  1. Abra la Functions page (Página de funciones) en la consola de Lambda.

  2. Elija una función.

  3. En Fuente de código, seleccione Cargar desde.

  4. Cargue el paquete de implementación.

  5. Seleccione Save.

Compilación de un paquete de implementación con Gradle

Utilice el tipo de compilación Zip para crear un paquete de implementación con el código de la función y las dependencias.

ejemplo build.gradle: tarea de compilación

task buildZip(type: Zip) { from compileJava from processResources into('lib') { from configurations.runtimeClasspath } }

Esta configuración de compilación produce un paquete de implementación en el directorio build/distributions. La tarea compileJava compila las clases de la función. La processResources tarea copia los recursos del proyecto Java en su directorio de destino, potencialmente procesando entonces. into('lib') A continuación, la instrucción copia las bibliotecas de dependencias de la ruta de clase de la compilación en una carpeta denominada lib.

ejemplo build.gradle: dependencias

dependencies { implementation platform('software.amazon.awssdk:bom:2.10.73') implementation 'software.amazon.awssdk:lambda' implementation 'com.amazonaws:aws-lambda-java-core:1.2.1' implementation 'com.amazonaws:aws-lambda-java-events:3.1.0' implementation 'com.google.code.gson:gson:2.8.6' implementation 'org.apache.logging.log4j:log4j-api:2.13.0' implementation 'org.apache.logging.log4j:log4j-core:2.13.0' runtimeOnly 'org.apache.logging.log4j:log4j-slf4j18-impl:2.13.0' runtimeOnly 'com.amazonaws:aws-lambda-java-log4j2:1.2.0' testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.0' }

Lambda carga los archivos JAR en orden alfabético Unicode. Si hay varios archivos JAR en el directorio lib que contienen la misma clase, se utiliza el primero. Puede utilizar el siguiente script de shell para identificar las clases duplicadas.

ejemplo 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

Compilación de un paquete de implementación con Maven

Para crear un paquete de implementación con Maven, use el complemento Maven Shade. El complemento crea un archivo JAR que contiene el código compilado de la función y todas sus dependencias.

ejemplo pom.xml: configuración del complemento

<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 crear el paquete de implementación, utilice el 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.1 in the shaded jar. [INFO] Including com.amazonaws:aws-lambda-java-events:jar:3.1.0 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] ------------------------------------------------------------------------

Este comando genera un archivo JAR en el directorio target.

Si utiliza la biblioteca de appender (aws-lambda-java-log4j2), también debe configurar un transformador para el complemento Maven Shade. La biblioteca de transformadores combina versiones de un archivo de caché que aparecen tanto en la biblioteca de appender como en Log4j.

ejemplo pom.xml: configuración del complemento con el appender 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>

Carga de un paquete de implementación con la API de Lambda

Para actualizar el código de una función con AWS Command Line Interface (AWS CLI) o AWS SDK, utilice la operación de API UpdateFunctionCode. Para el AWS CLI, utilice el comando update-function-code. El siguiente comando carga un paquete de implementación llamado my-function.zip en el directorio actual.

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

Debería ver los siguientes datos de salida:

{ "FunctionName": "my-function", "FunctionArn": "arn:aws:lambda:us-east-2:123456789012:function:my-function", "Runtime": "java8", "Role": "arn:aws:iam::123456789012:role/lambda-role", "Handler": "example.Handler", "CodeSha256": "Qf0hMc1I2di6YFMi9aXm3JtGTmcDbjniEuiYonYptAk=", "Version": "$LATEST", "TracingConfig": { "Mode": "Active" }, "RevisionId": "983ed1e3-ca8e-434b-8dc1-7d72ebadd83d", ... }

Si el paquete de implementación es mayor que 50 MB, no puede cargarlo directamente. Súbalo a un bucket de Amazon Simple Storage Service (Amazon S3) y señalar Lambda al objeto. Los comandos de ejemplo siguientes cargan un paquete de implementación en un bucket S3 llamado my-bucket y lo utilizan para actualizar el código de una función.

aws s3 cp my-function.zip s3://my-bucket

Debería ver los siguientes datos de salida:

upload: my-function.zip to s3://my-bucket/my-function
aws lambda update-function-code --function-name my-function \ --s3-bucket my-bucket --s3-key my-function.zip

Debería ver los siguientes datos de salida:

{ "FunctionName": "my-function", "FunctionArn": "arn:aws:lambda:us-east-2:123456789012:function:my-function", "Runtime": "java8", "Role": "arn:aws:iam::123456789012:role/lambda-role", "Handler": "example.Handler", "CodeSha256": "Qf0hMc1I2di6YFMi9aXm3JtGTmcDbjniEuiYonYptAk=", "Version": "$LATEST", "TracingConfig": { "Mode": "Active" }, "RevisionId": "983ed1e3-ca8e-434b-8dc1-7d72ebadd83d", ... }

Puede utilizar este método para cargar paquetes de funciones hasta alcanzar 250 MB (descomprimidos).

Carga de un paquete de implementación con AWS SAM

Puede usar el AWS SAM para automatizar las implementaciones del código de función, la configuración y las dependencias. AWS SAM es una extensión de AWS CloudFormation que proporciona una sintaxis simplificada para definir aplicaciones sin servidor. En la siguiente plantilla de ejemplo, se define una función con un paquete de implementación en el directorio build/distributions que usa Gradle:

ejemplo 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: java8 Description: Java function MemorySize: 512 Timeout: 10 # Function's execution role Policies: - AWSLambdaBasicExecutionRole - AWSLambda_ReadOnlyAccess - AWSXrayWriteOnlyAccess - AWSLambdaVPCAccessExecutionRole Tracing: Active

Para crear la función, utilice los comandos package y deploy. Estos comandos son personalizaciones de la CLI de AWS CLI. Contienen otros comandos que van a cargar el paquete de implementación en Amazon S3, reescribir la plantilla con el URI del objeto y actualizar el código de la función.

El siguiente script de ejemplo ejecuta una compilación de Gradle y carga el paquete de implementación que crea. Crea una pila de AWS CloudFormation la primera vez que la ejecuta. Si la pila ya existe, el script la actualiza.

ejemplo 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 ver un ejemplo completo, consulte las siguientes aplicaciones:

Aplicaciones de Lambda de ejemplo en Java

  • blank-java: una función de Java que muestra el uso de bibliotecas de Java de Lambda, el registro, las variables de entorno, las capas, el seguimiento de AWS X-Ray, las pruebas unitarias y el AWS SDK.

  • java-basic: función de Java mínima con pruebas unitarias y configuración de registro de variables.

  • java-events: una función mínima de Java que utiliza la última versión (3.0.0 y más reciente) de la biblioteca aws-lambda-java-events. Estos ejemplos no requieren utilizar AWS SDK como una dependencia.

  • s3-java: una función de Java que procesa los eventos de notificación de Amazon S3 y utiliza Java Class Library (JCL) para crear miniaturas de los archivos de imagen cargados.