Uso de capas para funciones de Lambda en Java - AWS Lambda

Uso de capas para funciones de Lambda en Java

Una capa de Lambda es un archivo .zip que contiene código o datos adicionales. Las capas suelen contener dependencias de biblioteca, un tiempo de ejecución personalizado o archivos de configuración. La creación de una capa implica tres pasos generales:

  1. Empaquete el contenido de su capa. Esto significa crear un archivo de archivo. zip que contenga las dependencias que desea usar en sus funciones.

  2. Cree la capa en Lambda.

  3. Agregue la capa a sus funciones.

Este tema contiene los pasos y las instrucciones sobre cómo empaquetar y crear correctamente una capa de Lambda en Java con dependencias de bibliotecas externas.

Requisitos previos

Para completar los pasos de esta sección, debe disponer de lo siguiente:

nota

Asegúrese de que la versión de Java a la que hace referencia Maven sea la misma que la versión de Java de la función que pretende implementar. Por ejemplo, para una función de Java 21, el comando mvn -v debería incluir la versión 21 de Java en el resultado:

Apache Maven 3.8.6 ... Java version: 21.0.2, vendor: Oracle Corporation, runtime: /Library/Java/JavaVirtualMachines/jdk-21.jdk/Contents/Home ...

A lo largo de este tema, haremos referencia a la aplicación de muestra layer-java en el repositorio de GitHub awsdocs. Esta aplicación contiene scripts que descargan las dependencias y generan las capas. La aplicación también contiene las funciones correspondientes que utilizan las dependencias de las capas. Tras crear una capa, puede implementar e invocar la función correspondiente para comprobar que todo funciona correctamente. Debido a que utiliza el tiempo de ejecución de Java 21 para las funciones, las capas también deben ser compatibles con Java 21.

La aplicación layer-java de ejemplo contiene un único ejemplo en dos subdirectorios. El directorio layer contiene un archivo pom.xml que define las dependencias de la capa, así como los scripts para generar la capa. El directorio function contiene una función de ejemplo que ayuda a comprobar el funcionamiento de la capa. Este tutorial explica cómo crear y empaquetar esta capa.

Compatibilidad de capas de Java con Amazon Linux

El primer paso para crear una capa consiste en agrupar todo el contenido de la capa en un archivo .zip. Dado que las funciones de Lambda se ejecutan en Amazon Linux, el contenido de la capa debe poder compilarse y crearse en un entorno de Linux.

El código Java está diseñado para ser independiente de la plataforma, por lo que puede empaquetar las capas en su máquina local aunque no utilice un entorno Linux. Tras cargar la capa de Java en Lambda, seguirá siendo compatible con Amazon Linux.

Rutas de capa para tiempos de ejecución de Java

Cuando agrega una capa a una función, Lambda carga el contenido de la capa en el directorio /opt de ese entorno de ejecución. Para cada tiempo de ejecución de Lambda, la variable PATH ya incluye rutas de carpeta específicas en el directorio /opt. Para garantizar que la variable PATH recoja el contenido de la capa, el archivo.zip de la capa, debe tener sus dependencias en las siguientes rutas de carpeta:

  • java/lib

Por ejemplo, el archivo.zip de capa resultante que cree en este tutorial tiene la siguiente estructura de directorios:

layer_content.zip └ java └ lib └ layer-java-layer-1.0-SNAPSHOT.jar

El archivo JAR layer-java-layer-1.0-SNAPSHOT.jar (un uber-jar que contiene todas las dependencias necesarias) está ubicado correctamente en el directorio java/lib. Esto garantiza que Lambda pueda localizar la biblioteca durante las invocaciones de funciones.

Empaquetado del contenido de la capa

En este ejemplo, empaquetará las dos bibliotecas Java siguientes en un único archivo JAR:

  • aws-lambda-java-core: conjunto mínimo de definiciones de interfaz para trabajar con Java en AWS Lambda

  • Jackson: un popular conjunto de herramientas de procesamiento de datos, especialmente para trabajar con JSON.

Siga los pasos que se indican a continuación para instalar y empaquetar el contenido de la capa.

Para instalar y empaquetar el contenido de la capa
  1. Clone el repositorio de aws-lambda-developer-guide de GitHub, que contiene el código de muestra que necesita en el directorio sample-apps/layer-java.

    git clone https://github.com/awsdocs/aws-lambda-developer-guide.git
  2. Navegue hasta el directorio layer de la aplicación de ejemplo layer-java. Este directorio contiene los scripts que usa para crear y empaquetar la capa correctamente.

    cd aws-lambda-developer-guide/sample-apps/layer-java/layer
  3. Examine el archivo pom.xml. En la sección <dependencies>, defina las dependencias que desea incluir en la capa, es decir, las bibliotecas aws-lambda-java-core y jackson-databind. Puede actualizar este archivo para incluir cualquier dependencia que desee incluir en su propia capa.

    ejemplo pom.xml
    <dependencies> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-core</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.17.0</version> </dependency> </dependencies>
    nota

    La sección <build> de este archivo pom.xml contiene dos complementos. maven-compiler-plugin que compila el código fuente. maven-shade-plugin que empaqueta sus artefactos en un único uber-jar.

  4. Asegúrese de tener los permisos para ejecutar ambos scripts.

    chmod 744 1-install.sh && chmod 744 2-package.sh
  5. Ejecute el script 1-install.sh mediante el siguiente comando:

    ./1-install.sh

    Este script ejecuta mvn clean install en el directorio actual. Esto crea el uber-jar con todas las dependencias necesarias en el directorio target/.

    ejemplo 1-install.sh
    mvn clean install
  6. Ejecute el script 2-package.sh mediante el siguiente comando:

    ./2-package.sh

    Este script crea la estructura de directorios java/lib que necesita para empaquetar correctamente el contenido de la capa. A continuación, copia el uber-jar del directorio /target al directorio java/lib recién creado. Finalmente, el script comprime el contenido del directorio java en un archivo llamado layer_content.zip. Este es el archivo .zip para su capa. Puede descomprimir el archivo y comprobar que contiene la estructura de archivos correcta, como se muestra en la sección Rutas de capa para tiempos de ejecución de Java.

    ejemplo 2-package.sh
    mkdir java mkdir java/lib cp -r target/layer-java-layer-1.0-SNAPSHOT.jar java/lib/ zip -r layer_content.zip java

Creación de la capa

En esta sección, seleccione el archivo layer_content.zip que generó en la sección anterior y cárguelo como una capa de Lambda. Puede cargar una capa mediante la AWS Management Console o la API de Lambda en la AWS Command Line Interface (AWS CLI). Al cargar el archivo .zip de la capa, en el siguiente comando de AWS CLI PublishLayerVersion, especifique java21 como tiempo de ejecución compatible y arm64 como arquitectura compatible.

aws lambda publish-layer-version --layer-name java-jackson-layer \ --zip-file fileb://layer_content.zip \ --compatible-runtimes java21 \ --compatible-architectures "arm64"

En la respuesta, anote el LayerVersionArn, que tiene este aspecto arn:aws:lambda:us-east-1:123456789012:layer:java-jackson-layer:1. Necesitará este nombre de recurso de Amazon (ARN) en el siguiente paso de este tutorial cuando agregue la capa a la función.

Agregue la capa a la función

En esta sección, despliega una función de Lambda de ejemplo que utiliza la biblioteca Jackson en su código de función y a continuación adjunta la capa. Para implementar la función, necesita un Definición de permisos de funciones de Lambda con un rol de ejecución. Si no dispone de un rol de ejecución existente, siga los pasos de la sección desplegable. De no ser así, vaya a la siguiente sección para implementar la función.

Para crear un rol de ejecución
  1. Abra la página Roles en la consola de IAM.

  2. Elija Crear rol.

  3. Cree un rol con las propiedades siguientes.

    • Trusted entity (Entidad de confianza).Lambda:.

    • Permisos: AWSLambdaBasicExecutionRole.

    • Nombre de rol: lambda-role.

    La política AWSLambdaBasicExecutionRole tiene permisos que la función necesita para escribir registros a Registros de CloudWatch.

Para implementar la función de Lambda
  1. Vaya al directorio function/. Si se encuentra actualmente en el directorio layer/, ejecute el siguiente comando:

    cd ../function
  2. Revise el código de la función. La función toma a Map<String, String> como entrada y usa Jackson para escribir la entrada como una cadena JSON antes de convertirla en un objeto Java F1Car predefinido. Por último, la función utiliza los campos del objeto F1Car para crear una cadena que devuelve la función.

    package example; import com.amazonaws.services.lambda.runtime.Context; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; import java.util.Map; public class Handler { public String handleRequest(Map<String, String> input, Context context) throws IOException { // Parse the input JSON ObjectMapper objectMapper = new ObjectMapper(); F1Car f1Car = objectMapper.readValue(objectMapper.writeValueAsString(input), F1Car.class); StringBuilder finalString = new StringBuilder(); finalString.append(f1Car.getDriver()); finalString.append(" is a driver for team "); finalString.append(f1Car.getTeam()); return finalString.toString(); } }
  3. Cree el proyecto usando el siguiente comando de Maven:

    mvn package

    Este comando genera un archivo JAR en el directorio target/ denominado layer-java-function-1.0-SNAPSHOT.jar.

  4. Implemente la función. En el siguiente comando AWS CLI, sustituya el parámetro --role por el ARN del rol de ejecución:

    aws lambda create-function --function-name java_function_with_layer \ --runtime java21 \ --architectures "arm64" \ --handler example.Handler::handleRequest \ --timeout 30 \ --role arn:aws:iam::123456789012:role/lambda-role \ --zip-file fileb://target/layer-java-function-1.0-SNAPSHOT.jar

En este punto, si lo desea, puede intentar invocar su función antes de adjuntar la capa. Si lo intenta, aparecerá un ClassNotFoundException porque la función no puede hacer referencia al paquete requests. Utilice el comando AWS CLI para invocar la función:

aws lambda invoke --function-name java_function_with_layer \ --cli-binary-format raw-in-base64-out \ --payload '{ "driver": "Max Verstappen", "team": "Red Bull" }' response.json

Debería ver un resultado con un aspecto similar al siguiente:

{ "StatusCode": 200, "FunctionError": "Unhandled", "ExecutedVersion": "$LATEST" }

Para ver el error específico, abra el archivo de salida response.json. Debería ver un ClassNotFoundException con el siguiente mensaje de error:

"errorMessage":"com.fasterxml.jackson.databind.ObjectMapper","errorType":"java.lang.ClassNotFoundException"

A continuación, adjunte la capa a la función. En el siguiente comando AWS CLI, sustituya el parámetro --layers por el ARN de la versión de capa que indicó anteriormente:

aws lambda update-function-configuration --function-name java_function_with_layer \ --cli-binary-format raw-in-base64-out \ --layers "arn:aws:lambda:us-east-1:123456789012:layer:java-jackson-layer:1"

Finalmente, intente invocar su función usando el siguiente comando AWS CLI:

aws lambda invoke --function-name java_function_with_layer \ --cli-binary-format raw-in-base64-out \ --payload '{ "driver": "Max Verstappen", "team": "Red Bull" }' response.json

Debería ver un resultado con un aspecto similar al siguiente:

{ "StatusCode": 200, "ExecutedVersion": "$LATEST" }

Esto indica que la función pudo usar la dependencia de Jackson para ejecutar la función correctamente. Puede comprobar que el archivo de salida response.json contiene la cadena devuelta correcta:

"Max Verstappen is a driver for team Red Bull"

A menos que desee conservar los recursos que creó para este tutorial, puede eliminarlos ahora. Si elimina los recursos de AWS que ya no utiliza, evitará gastos innecesarios en su Cuenta de AWS.

Para eliminar la capa de Lambda
  1. Abra la página de Capas de la consola de Lambda.

  2. Seleccione la capa que ha creado.

  3. Elija Eliminar, luego, vuelva a elegir Eliminar.

Cómo eliminar la función de Lambda
  1. Abra la página de Funciones en la consola de Lambda.

  2. Seleccione la función que ha creado.

  3. Elija Acciones, Eliminar.

  4. Escriba delete en el campo de entrada de texto y seleccione Delete (Eliminar).