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).
Secciones
- Requisitos previos
- Herramientas y bibliotecas
- Compilación de un paquete de implementación con Gradle
- Compilación de un paquete de implementación con Maven
- Carga de un paquete de despliegue con la consola de Lambda
- Carga de un paquete de implementación con la API de Lambda
- Carga de un paquete de implementación con AWS SAM
Requisitos previos
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:
-
com.amazonaws:aws-lambda-java-core
(obligatoria): define interfaces de métodos de controlador y el objeto contextual que el entorno de ejecución pasa al controlador. Si define sus propios tipos de entrada, esta es la única biblioteca que necesita. -
com.amazonaws:aws-lambda-java-events
: tipos de entrada de eventos procedentes de servicios que invocan funciones de Lambda. -
com.amazonaws:aws-lambda-java-log4j2
: una biblioteca de appender de Log4j 2 para Apache que puede usar para agregar el ID solicitado en la invocación actual a los registros de funciones. -
AWSSDK para Java 2.0
: el SDK oficial de AWS para el lenguaje de programación Java.
Estas bibliotecas están disponibles en el repositorio central de Maven
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. Cargue el paquete de despliegue a través de la consola de Lambda, la API de Lambda o AWS Serverless Application Model (AWS SAM).
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.
Compilación de un paquete de implementación con Gradle
Utilice el tipo de compilación Zip
para crear un paquete de despliegue con el código de función y las dependencias de Gradle. Este es un ejemplo de un archivo build.gradle de muestra completo
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 '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'
... }
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
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.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] ------------------------------------------------------------------------
Este comando genera un archivo JAR en el directorio target
.
nota
Si trabaja con un JAR de varias versiones (MRJAR)lib
y comprimirlo antes de subir el paquete de despliegue a Lambda. De lo contrario, es posible que Lambda no descomprima correctamente el archivo JAR, lo que hará que se ignore el archivo MANIFEST.MF
.
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 despliegue con la consola de Lambda
Puede cargar un paquete de despliegue en cualquier función existente mediante la consola de Lambda.
Para cargar un paquete de implementación con la consola de Lambda
Abra la página de Functions
(Funciones) en la consola de Lambda. -
Elija una función.
-
En Fuente de código, seleccione Cargar desde.
-
Cargue el paquete de implementación.
-
Seleccione Save.
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
-
java-basic
: una colección de funciones Java mínimas con pruebas unitarias y configuración de registro variable. -
java-events
: una colección de funciones Java que contiene un código básico sobre cómo gestionar los eventos de varios servicios, como Amazon API Gateway, Amazon SQS y Amazon Kinesis. Estas funciones utilizan la última versión de la biblioteca aws-lambda-java-events (3.0.0 y más recientes). 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. -
Uso de API Gateway para invocar una función de Lambda: una función Java que escanea una tabla de Amazon DynamoDB que contiene información sobre los empleados. Luego, utiliza Amazon Simple Notification Service para enviar un mensaje de texto a los empleados que celebran sus aniversarios laborales. En este ejemplo, se utiliza API Gateway para invocar la función.