Distribuisci funzioni Lambda per Java con archivi di file .zip o JAR - AWS Lambda

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Distribuisci funzioni Lambda per Java con archivi di file .zip o JAR

Il codice della AWS Lambda funzione è costituito da script o programmi compilati e dalle relative dipendenze. Utilizza un pacchetto di implementazione per distribuire il codice della funzione a Lambda. Lambda supporta due tipi di pacchetti di implementazione: immagini di container e archivi di file .zip.

Questa pagina descrive come creare il pacchetto di distribuzione come file.zip o file Jar, quindi utilizzare il pacchetto di distribuzione per distribuire il codice della funzione su (). AWS Lambda AWS Command Line Interface AWS CLI

Prerequisiti

AWS CLI È uno strumento open source che consente di interagire con i AWS servizi utilizzando i comandi nella shell della riga di comando. Per completare le fasi riportate in questa sezione, è necessario:

Strumenti e librerie

Lambda fornisce le seguenti librerie per le funzioni Java:

Queste librerie sono disponibili tramite Maven Central Repository. Aggiungile alla definizione di build come segue.

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>

Per creare un pacchetto di distribuzione, compila il codice della funzione e le dipendenze in un singolo file .zip o un file di archivio Java (JAR). Per Gradle, utilizza il tipo di build Zip. Per Apache Maven, utilizza il plugin Maven Shade. Per caricare il pacchetto di distribuzione, usa la console Lambda, l'API Lambda o (). AWS Serverless Application Model AWS SAM

Nota

Per mantenere contenute le dimensioni del pacchetto di distribuzione, raggruppa le dipendenze della funzione in livelli. I livelli consentono di gestire le dipendenze in modo indipendente, possono essere utilizzate da più funzioni e possono essere condivisi con altri account. Per ulteriori informazioni, consulta Gestione delle dipendenze Lambda con livelli.

Creazione di un pacchetto di distribuzione con Gradle

Per creare un pacchetto di implementazione con il codice e le dipendenze della funzione in Gradle, utilizza il tipo di compilazione Zip. Ecco un esempio tratto da un file build.gradle di esempio completo:

Esempio build.gradle: attività di compilazione
task buildZip(type: Zip) { into('lib') { from(jar) from(configurations.runtimeClasspath) } }

Questa configurazione di build crea un pacchetto di distribuzione nella directory build/distributions. All'interno dell'istruzione into('lib'), l'attività jar assembla un archivio jar contenente le classi principali in una cartella denominata lib. Inoltre, l'istruzione configurations.runtimeClassPath copia le librerie delle dipendenze dal classpath della build in una cartella denominata lib.

Esempio build.gradle: dipendenze
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 carica i file JAR in ordine alfabetico Unicode. Se più file JAR nella directory lib contengono la stessa classe, viene utilizzato il primo. È possibile utilizzare il seguente script di shell per identificare le classi duplicate:

Esempio 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

Creare un livello Java per dipendenze

Nota

L’utilizzo di livelli con funzioni in un linguaggio compilato come Java potrebbe non offrire gli stessi vantaggi di un linguaggio interpretato come Python. Siccome Java è un linguaggio compilato, le funzioni devono comunque caricare manualmente gli assembly condivisi in memoria durante la fase di inizializzazione, per cui i tempi di avvio a freddo possono aumentare. È preferibile, invece, includere qualunque codice condiviso in fase di compilazione per sfruttare le ottimizzazioni integrate del compilatore.

Le istruzioni in questa sezione spiegano come includere dipendenze in un livello. Per istruzioni sull’inclusione di dipendenze in un pacchetto di implementazione, consulta Creazione di un pacchetto di distribuzione con Gradle o Creazione di un pacchetto di distribuzione con Maven.

Quando si aggiunge un livello a una funzione, Lambda carica il contenuto del livello nella directory /opt di quell'ambiente di esecuzione. Per ogni runtime Lambda, la variabile PATH include percorsi di cartelle specifici nella directory /opt. Per garantire che la PATH variabile raccolga il contenuto del layer, il file Layer .zip dovrebbe avere le sue dipendenze nei seguenti percorsi di cartella:

  • java/lib (CLASSPATH)

Ad esempio, la struttura del file .zip del livello potrebbe essere simile alla seguente:

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

Lambda rileva automaticamente tutte le librerie nella directory /opt/lib e tutti i file binari nella directory /opt/bin. Per accertarti che Lambda trovi correttamente il contenuto del tuo livello, crea un livello con la seguente struttura:

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

Dopo aver creato un pacchetto del livello, consulta Creazione ed eliminazione di livelli in Lambda e Aggiunta di livelli alle funzioni per completare l’impostazione del livello.

Creazione di un pacchetto di distribuzione con Maven

Per creare un pacchetto di distribuzione con Maven, utilizzare il plugin Maven Shade. Il plugin crea un file JAR che contiene il codice della funzione compilato e tutte le relative dipendenze.

Esempio pom.xml: configurazione del 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>

Per compilare il pacchetto di distribuzione, utilizzare il 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] ------------------------------------------------------------------------

Questo comando genera un file JAR nella directory target.

Nota

Se stai lavorando con un JAR multi-rilascio (MRJAR), devi includere l'MRJAR (ossia il JAR shaded prodotto dal plug-in Maven Shade) nella directory lib e comprimerlo prima di caricare il pacchetto di implementazione in Lambda. In caso contrario, Lambda potrebbe non decomprimere correttamente il file JAR, facendo sì che il file MANIFEST.MF venga ignorato.

Se si utilizza la libreria appender (aws-lambda-java-log4j2), è necessario configurare anche un trasformatore per il plugin Maven Shade. La libreria del trasformatore combina le versioni di un file di cache presenti sia nella libreria appender che in Log4j.

Esempio pom.xml: configurazione del plugin con l'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>

Caricamento di un pacchetto di implementazione con la console Lambda

Per creare una nuova funzione, devi prima creare la funzione nella console, quindi devi caricare il tuo file .zip o JAR. Per aggiornare una funzione esistente, apri la pagina relativa alla tua funzione, quindi segui la stessa procedura per aggiungere il file .zip o JAR aggiornato.

Se il file del pacchetto di implementazione ha dimensioni inferiori a 50 MB, è possibile creare o aggiornare una funzione caricando il file direttamente dal computer locale. Per i file .zip o JAR di dimensioni superiori a 50 MB, prima è necessario caricare il pacchetto in un bucket Amazon S3. Per istruzioni su come caricare un file in un bucket Amazon S3 utilizzando AWS Management Console, consulta la Guida introduttiva ad Amazon S3. Per caricare file utilizzando la AWS CLI, consulta Move objects nella Guida per l'AWS CLI utente.

Nota

Non è possibile modificare il tipo di pacchetto di distribuzione (.zip o immagine del contenitore) per una funzione esistente. Ad esempio, non è possibile convertire una funzione di immagine del contenitore per utilizzare un archivio di file.zip. È necessario creare una nuova funzione.

Creazione di una nuova funzione (console)
  1. Apri la pagina Funzioni della console Lambda e scegli Crea funzione.

  2. Scegli Author from scratch (Crea da zero).

  3. In Basic information (Informazioni di base) eseguire queste operazioni:

    1. In Nome funzione, inserisci il nome della funzione.

    2. Per Runtime, seleziona il runtime che desideri utilizzare.

    3. (Facoltativo) Per Architettura, scegli l'architettura del set di istruzioni per la funzione. L'architettura predefinita è x86_64. Assicurati che il pacchetto di implementazione per la tua funzione sia compatibile con l'architettura del set di istruzioni scelta.

  4. (Opzionale) In Autorizzazioni espandere Modifica ruolo di esecuzione predefinito. Puoi creare un nuovo ruolo di esecuzione o utilizzare un ruolo esistente.

  5. Scegli Crea funzione. Lambda crea una funzione di base "Hello world" utilizzando il runtime scelto.

Caricamento di un archivio .zip o JAR dal computer locale (console)
  1. Nella pagina Funzioni della console Lambda, scegli la funzione per cui vuoi caricare il file .zip o JAR.

  2. Scegli la scheda Codice.

  3. Nel riquadro Origine del codice, scegli Carica da.

  4. Scegli File .zip o .jar.

  5. Per caricare il file .zip o JAR, procedi come segue:

    1. Seleziona Carica, quindi seleziona il tuo file .zip o JAR nel selettore di file.

    2. Seleziona Apri.

    3. Selezionare Salva.

Caricamento di un archivio .zip o JAR da un bucket Amazon S3 (console)
  1. Nella pagina Funzioni della console Lambda, scegli la funzione per cui vuoi caricare un nuovo file .zip o JAR.

  2. Scegli la scheda Codice.

  3. Nel riquadro Origine del codice, scegli Carica da.

  4. Scegli Posizione Amazon S3.

  5. Incolla l'URL del link Amazon S3 del tuo file .zip e scegli Salva.

Caricamento di un pacchetto di distribuzione con AWS CLI

È possibile utilizzare la AWS CLI per creare una nuova funzione o aggiornare una funzione esistente mediante un file .zip o JAR. Usa la funzione create-function e update-function-codei comandi per distribuire il tuo pacchetto.zip o JAR. Se il file ha dimensioni inferiori a 50 MB, è possibile caricare il pacchetto da una posizione nella macchina di compilazione locale. Per i file di dimensioni superiori, è necessario caricare il pacchetto .zip o JAR da un bucket Amazon S3. Per istruzioni su come caricare un file su un bucket Amazon S3 utilizzando AWS CLI, consulta Move objects nella User Guide.AWS CLI

Nota

Se carichi il tuo file.zip o JAR da un bucket Amazon S3 utilizzando AWS CLI il, il bucket deve trovarsi nella stessa posizione della Regione AWS tua funzione.

Per creare una nuova funzione utilizzando un file.zip o JAR con AWS CLI, devi specificare quanto segue:

  • Il nome della funzione (--function-name)

  • Il runtime della tua funzione (--runtime)

  • Il nome della risorsa Amazon (ARN) del ruolo di esecuzione della funzione (--role)

  • Il nome del metodo del gestore nel codice della funzione (--handler)

È inoltre necessario specificare la posizione del file .zip o JAR. Se il file .zip o JAR si trova in una cartella nella macchina di compilazione locale, utilizza l'opzione --zip-file per specificare il percorso del file, come mostrato nel seguente comando di esempio.

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

Per specificare la posizione del file .zip in un bucket Amazon S3, utilizza l'opzione --code illustrata nel seguente comando di esempio. È necessario utilizzare il parametro S3ObjectVersion solo per gli oggetti con controllo delle versioni.

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=DOC-EXAMPLE-BUCKET,S3Key=myFileName.zip,S3ObjectVersion=myObjectVersion

Per aggiornare una funzione esistente mediante la CLI, specifica il nome della funzione utilizzando il parametro --function-name. È inoltre necessario specificare la posizione del file .zip che desideri utilizzare per aggiornare il codice della funzione. Se il file .zip si trova in una cartella sulla macchina di compilazione locale, utilizza l'opzione --zip-file per specificare il percorso del file, come mostrato nel seguente comando di esempio.

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

Per specificare la posizione del file .zip in un bucket Amazon S3, utilizza le opzioni --s3-bucket e --s3-key come illustrato nel seguente comando di esempio. È necessario utilizzare il parametro --s3-object-version solo per gli oggetti con controllo delle versioni.

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

Caricamento di un pacchetto di distribuzione con AWS SAM

È possibile utilizzarlo AWS SAM per automatizzare le distribuzioni del codice funzionale, della configurazione e delle dipendenze. AWS SAM è un'estensione AWS CloudFormation che fornisce una sintassi semplificata per la definizione di applicazioni serverless. Il modello di esempio seguente definisce una funzione con un pacchetto di distribuzione nella directory build/distributions utilizzata da Gradle:

Esempio 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

Per creare la funzione, utilizzare i comandi package e deploy. Questi comandi sono personalizzazioni per l' AWS CLI. Essi avvolgono altri comandi per caricare il pacchetto di distribuzione Amazon S3, riscrivere il modello con l'URI dell'oggetto e aggiornare il codice della funzione.

Lo script di esempio seguente esegue una compilazione Gradle e carica il pacchetto di distribuzione creato. Crea uno AWS CloudFormation stack la prima volta che lo esegui. Se lo stack esiste già, lo script lo aggiorna.

Esempio 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

Per un esempio pratico completo, consulta le seguenti applicazioni di esempio:

Applicazioni Lambda di esempio in Java
  • java17-examples: una funzione Java che dimostra come utilizzare un record Java per rappresentare un oggetto di dati dell'evento di input.

  • java-basic: una raccolta di funzioni Java minimali con unit test e configurazione della registrazione dei log delle variabili.

  • java-events: una raccolta di funzioni Java che contengono codice skeleton per la gestione degli eventi di vari servizi, ad esempio Gateway Amazon API, Amazon SQS e Amazon Kinesis. Queste funzioni utilizzano l'ultima versione della aws-lambda-java-eventslibreria (3.0.0 e successive). Questi esempi non richiedono l' AWS SDK come dipendenza.

  • s3-java – Una funzione Java che elabora gli eventi di notifica da Amazon S3 e utilizza la Java Class Library (JCL) per creare anteprime dai file di immagine caricati.

  • Utilizza API Gateway per richiamare una funzione Lambda: una funzione Java che esegue la scansione di una tabella Amazon DynamoDB che contiene informazioni sui dipendenti. Quindi utilizza Amazon Simple Notification Service per inviare un messaggio di testo ai dipendenti per festeggiare i loro anniversari di lavoro. Questo esempio usa API Gateway per richiamare la funzione.