Maison  >  Article  >  Java  >  Fonction Lambda avec GraalVM Native Image - Procédure partielle pour développer et déployer la fonction Lambda avec un runtime personnalisé

Fonction Lambda avec GraalVM Native Image - Procédure partielle pour développer et déployer la fonction Lambda avec un runtime personnalisé

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-10-21 16:16:30833parcourir

Introduction

Dans la partie 1 de la série, nous avons donné une introduction à GraalVM et en particulier à ses capacités Native Image. Nous avons également expliqué ses avantages pour les applications Serverless. Dans cette partie de la série, nous expliquerons comment développer et déployer la fonction AWS Lambda avec un runtime personnalisé contenant GraalVM Native Image.

Exemple d'application

Par souci d'explication, nous utiliserons notre exemple d'application. Dans cette application, nous allons créer et récupérer des produits et utiliser DynamoDB comme base de données NoSQL. Nous réutiliserons l'application présentée dans l'article Mesurer les démarrages à froid de Java 21 Lambda et l'ajusterons pour qu'elle soit déployée en tant que Lambda Custom Runtime contenant GraalVM Native Image.

Lambda function with GraalVM Native Image - Part ow to develop and deploy Lambda function with custom runtime

Configuration générale

Afin de créer une image native GraalVM, nous devrons procéder comme suit :

  • Configurez l'instance m5.large AWS Cloud9 EC2. Vous pouvez bien sûr utiliser votre propre environnement Linux (local).
  • Installer SDKMAN
curl -s "https://get.sdkman.io" | bash  

source "/home/ec2-user/.sdkman/bin/sdkman-init.sh"
  • Installez la dernière version de GraalVM. J'ai utilisé la version 22 dans mon exemple (mais vous pouvez utiliser la plus récente) :
sdk install java 22.0.1-graal  (or use the newest GraalVM version)
  • Installer l'image native
sudo yum install gcc glibc-devel zlib-devel 
sudo dnf install gcc glibc-devel zlib-devel libstdc++-static
  • Installez Maven capable de construire avec la version GraalVM installée. Nous avons besoin d'une version Maven capable de gérer la version Java 21 et supérieure du code source. Par exemple :
wget https://mirrors.estointernet.in/apache/maven/maven-3/3.8.5/binaries/apache-maven-3.8.5-bin.tar.gz tar -xvf apache-maven-3.8.5-bin.tar.gz sudo mv apache-maven-3.8.5 /opt/

M2_HOME='/opt/apache-maven-3.8.5' 

PATH="$M2_HOME/bin:$PATH" 

export PATH

Si ce miroir devient indisponible, veuillez en utiliser un autre disponible pour votre système d'exploitation.

Rendre un exemple d'application compatible avec GraalVM Native Image

Pour que notre exemple d'application puisse s'exécuter en tant qu'image native GraalVM, nous devons déclarer toutes les classes dont les objets seront instanciés par réflexion. Ces classes devaient être connues du compilateur AOT au moment de la compilation. Cela se produit dans Reflect.json. Comme nous pouvons le voir, nous devons y déclarer

  • toutes nos fonctions Lambda comme GetProductByIdHandler et CreateProductHandler
  • entités telles que Product et Products qui seront converties à partir de la charge utile JSON et inversement
  • APIGatewayProxyRequestEvent et toutes ses classes internes car nous avons déclaré ce type d'événement comme événement de demande dans nos fonctions Lambda comme GetProductByIdHandler et CreateProductHandler
  • org.joda.time.DateTime qui sera utilisé pour convertir l'horodatage à partir de String et inversement, qui fait partie des événements de demande et de réponse du proxy APIGateway

Afin d'éviter les erreurs avec les enregistreurs lors de l'initialisation décrite dans l'article Initialisation de classe dans l'image native, nous devons ajouter les arguments de construction GraalVM Native Image dans le fichier native-image.properties.

curl -s "https://get.sdkman.io" | bash  

source "/home/ec2-user/.sdkman/bin/sdkman-init.sh"

Le fichier native-image.properties doit être placé dans le META-INF/native-image/${MavenGroupIid}/${MavenArtifactId}

Comme nous utilisons slf4j-simple Logger dans pom.xml, nous devons placer native-image.properties dans le chemin META-INF/native-image/org.slf4j/slf4j-simple.

Exécution personnalisée Lambda

Afin de déployer la fonction Lambda en tant qu'environnement d'exécution personnalisé, nous devons tout regrouper dans le fichier avec l'extension .zip qui inclut le fichier portant le nom bootstrap. Ce fichier peut être soit l'image native GraalVM dans notre cas, soit contenir des instructions sur la façon d'invoquer l'image native GraalVM placée dans un autre fichier. Explorons-le.

Création d'une image native GraalVM

Nous construirons automatiquement l'image GraalVM Native dans la phase de package définie dans le pom.xml. La partie pertinente est définie dans le plugin suivant :

sdk install java 22.0.1-graal  (or use the newest GraalVM version)

Nous utilisons native-image-maven-plugin des outils org.graalvm.nativeimage et exécutons native-image dans la phase de package. Ce plugin nécessite la définition de la classe principale que la fonction Lambda ne possède pas. C'est pourquoi nous utilisons Lambda Runtime GraalVM et définissons sa classe principale com.formkiq.lambda.runtime.graalvm.LambdaRuntime. Lambda Runtime GraalVM est une bibliothèque Java qui facilite la conversion d'AWS Lambda écrit en langage de programmation Java en GraalVM. Nous l'avons défini précédemment dans pom.xml comme dépendance

sudo yum install gcc glibc-devel zlib-devel 
sudo dnf install gcc glibc-devel zlib-devel libstdc++-static

Nous donnons ensuite le nom de l'image native aws-pure-lambda-java21-graalvm-native-image et incluons certains arguments GraalVM Native Image et reflect.json préalablement définis.

wget https://mirrors.estointernet.in/apache/maven/maven-3/3.8.5/binaries/apache-maven-3.8.5-bin.tar.gz tar -xvf apache-maven-3.8.5-bin.tar.gz sudo mv apache-maven-3.8.5 /opt/

M2_HOME='/opt/apache-maven-3.8.5' 

PATH="$M2_HOME/bin:$PATH" 

export PATH

Afin de compresser l'image native GraalVM construite en tant que function.zip requis par Lambda Custom Runtime, nous utilisons le plugin maven-assembly :

Args=--allow-incomplete-classpath \
    --initialize-at-build-time=org.slf4j.simple.SimpleLogger,\
      org.slf4j.LoggerFactory
    -- --trace-class-initialization=org.slf4j.simple.SimpleLogger,\
      org.slf4j.LoggerFactory

Le nom final que nous définissons comme fonction et l'identifiant comme native-zip Nous incluons également l'assembly native.xml. Cet assembly définit le format de fichier comme zip (le nom complet du fichier sera ${finalName}-${id}.zip, dans notre cas function-native-zip.zip), ajoute l'image native GraalVM précédemment construite avec le nom aws-pure-lambda-java21-graalvm-native-image et ajoute le bootstrap déjà défini qui invoquait essentiellement l'image native GraalVM :

<plugin>
      <groupId>org.graalvm.nativeimage</groupId>
      <artifactId>native-image-maven-plugin</artifactId>
      <version>21.2.0</version>
      <executions>
            <execution>
                  <goals>
                        <goal>native-image</goal>
                  </goals>
                  <phase>package</phase>
            </execution>
      </executions>
      <configuration>
            <skip>false</skip>
            <mainClass>com.formkiq.lambda.runtime.graalvm.LambdaRuntime</mainClass>
            <imageName>aws-pure-lambda-java21-graalvm-native-image</imageName>
            <buildArgs>
                  --no-fallback
                  --enable-http
                  -H:ReflectionConfigurationFiles=../src/main/reflect.json
                </buildArgs>
      </configuration>
</plugin>

En fin de compte, nous devons créer une image native GraalVM conditionnée sous forme de fichier zip qui peut être déployé en tant que Lambda Custom Runtime avec :

<dependency>
   <groupId>com.formkiq</groupId>
   <artifactId>lambda-runtime-graalvm</artifactId>
   <version>2.3.1</version>
</dependency>

Déploiement de l'image native GraalVM en tant que runtime personnalisé Lambda

Dans le modèle AWS SAM, nous utilisons le runtime Lambda comme provided.al2023, qui est la version la plus récente du runtime personnalisé) et fournissons le chemin d'accès à la fonction-native-zip GraalVM Native Image précédemment construite. zip.

  <buildArgs>
    --no-fallback
    --enable-http
    -H:ReflectionConfigurationFiles=../src/main/reflect.json
 </buildArgs>

Nous sommes maintenant prêts à déployer notre application avec

curl -s "https://get.sdkman.io" | bash  

source "/home/ec2-user/.sdkman/bin/sdkman-init.sh"

Conclusion

Dans cette partie de la série, nous avons expliqué comment développer et déployer la fonction AWS Lambda avec un runtime personnalisé contenant GraalVM Native Image. Dans la prochaine partie de la série, nous mesurerons les temps de démarrage à froid et à chaud de la fonction Lambda pour un tel scénario et pour différents paramètres de mémoire de la fonction Lambda.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn