Heim  >  Artikel  >  Java  >  Lambda-Funktion mit GraalVM Native Image – Teilweise zum Entwickeln und Bereitstellen einer Lambda-Funktion mit benutzerdefinierter Laufzeit

Lambda-Funktion mit GraalVM Native Image – Teilweise zum Entwickeln und Bereitstellen einer Lambda-Funktion mit benutzerdefinierter Laufzeit

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-10-21 16:16:30837Durchsuche

Einführung

Im ersten Teil der Serie haben wir eine Einführung in die GraalVM und insbesondere ihre Native Image-Fähigkeiten gegeben. Wir haben auch die Vorteile für serverlose Anwendungen erläutert. In diesem Teil der Serie erklären wir, wie man AWS Lambda-Funktionen mit benutzerdefinierter Laufzeit entwickelt und bereitstellt, die GraalVM Native Image enthält.

Beispielanwendung

Zur Erläuterung verwenden wir unsere Beispielanwendung. In dieser Anwendung erstellen und rufen wir Produkte ab und verwenden DynamoDB als NoSQL-Datenbank. Wir werden die im Artikel Messen von Kaltstarts von Java 21 Lambda vorgestellte Anwendung wiederverwenden und sie so anpassen, dass sie als Lambda Custom Runtime mit GraalVM Native Image bereitgestellt wird.

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

Allgemeine Einrichtung

Um das GraalVM Native Image zu erstellen, müssen wir Folgendes tun:

  • Richten Sie die m5.large AWS Cloud9 EC2-Instanz ein. Sie können natürlich Ihre eigene (lokale) Linux-Umgebung verwenden.
  • Installieren Sie SDKMAN
curl -s "https://get.sdkman.io" | bash  

source "/home/ec2-user/.sdkman/bin/sdkman-init.sh"
  • Installieren Sie die neueste GraalVM-Version. Ich habe in meinem Beispiel Version 22 verwendet (Sie können aber auch die neueste verwenden):
sdk install java 22.0.1-graal  (or use the newest GraalVM version)
  • Natives Image installieren
sudo yum install gcc glibc-devel zlib-devel 
sudo dnf install gcc glibc-devel zlib-devel libstdc++-static
  • Installieren Sie Maven, das mit der installierten GraalVM-Version erstellen kann. Wir benötigen eine Maven-Version, die mit Java 21 und einer höheren Version des Quellcodes umgehen kann. Zum Beispiel :
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

Wenn dieser Spiegel nicht mehr verfügbar ist, verwenden Sie bitte einen anderen, der für Ihr Betriebssystem verfügbar ist.

Beispielanwendung GraalVM Native Image fähig machen

Damit unsere Beispielanwendung als GraalVM Native Image ausgeführt werden kann, müssen wir alle Klassen deklarieren, welche Objekte pro Reflexion instanziiert werden. Diese Klassen mussten dem AOT-Compiler zur Kompilierungszeit bekannt sein. Dies geschieht in Reflect.json. Wie wir sehen, müssen wir es dort deklarieren

  • alle unsere Lambda-Funktionen wie GetProductByIdHandler und CreateProductHandler
  • Entitäten wie „Produkt“ und „Produkte“, die von der JSON-Nutzlast und zurück konvertiert werden
  • APIGatewayProxyRequestEvent und alle seine inneren Klassen, da wir diesen Ereignistyp in unseren Lambda-Funktionen wie GetProductByIdHandler und CreateProductHandler als Anforderungsereignis deklariert haben
  • org.joda.time.DateTime, das zum Konvertieren des Zeitstempels aus einem String und zurück verwendet wird, der Teil der APIGateway-Proxy-Anforderungs- und Antwortereignisse ist

Um Fehler mit Loggern während der im Artikel Klasseninitialisierung in Native Image beschriebenen Initialisierung zu vermeiden, müssen wir GraalVM Native Image-Build-Argumente in den native-image.properties hinzufügen.

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

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

Die native-image.properties sollten in META-INF/native-image/${MavenGroupIid}/${MavenArtifactId}

platziert werden

Da wir den slf4j-simple Logger in pom.xml verwenden, müssen wir native-image.properties im Pfad META-INF/native-image/org.slf4j/slf4j-simple platzieren.

Benutzerdefinierte Lambda-Laufzeit

Um die Lambda-Funktion als benutzerdefinierte Laufzeit bereitzustellen, müssen wir alles in die Datei mit der Erweiterung .zip packen, die die Datei mit dem Namen bootstrap enthält. Diese Datei kann in unserem Fall entweder das GraalVM Native Image sein oder Anweisungen zum Aufrufen des GraalVM Native Image in einer anderen Datei enthalten. Lass es uns erkunden.

Erstellen eines nativen GraalVM-Images

Wir erstellen das GraalVM Native-Image automatisch in der Paketphase, die in pom.xml definiert ist. Der relevante Teil ist im folgenden Plugin definiert:

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

Wir verwenden das Native-Image-Maven-Plugin von org.graalvm.nativeimage Tools und führen Native-Image in der Paketphase aus. Dieses Plugin erfordert die Definition der Hauptklasse, die die Lambda-Funktion nicht hat. Deshalb verwenden wir Lambda Runtime GraalVM und definieren seine Hauptklasse com.formkiq.lambda.runtime.graalvm.LambdaRuntime. Lambda Runtime GraalVM ist eine Java-Bibliothek, die es einfach macht, AWS Lambda, das in der Programmiersprache Java geschrieben ist, in die GraalVM zu konvertieren. Wir haben es zuvor in pom.xml als Abhängigkeit
definiert

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

Wir geben dann dem nativen Image einen Namen aws-pure-lambda-java21-graalvm-native-image und fügen einige GraalVM Native Image-Argumente und zuvor definierte reflect.json ein.

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

Um das erstellte GraalVM Native Image als function.zip zu komprimieren, das von Lambda Custom Runtime benötigt wird, verwenden wir das Maven-Assembly-Plugin:

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

Den endgültigen Namen definieren wir als Funktion und die ID als native-zip. Wir schließen auch die native.xml-Assembly ein. Diese Assembly definiert das Dateiformat als zip (der vollständige Dateiname lautet ${finalName}-${id}.zip, in unserem Fall function-native-zip.zip) und fügt das zuvor erstellte GraalVM Native Image mit dem Namen aws-pure-lambda-java21-graalvm-native-image und fügt den bereits definierten Bootstrap hinzu, der im Grunde das GraalVM Native Image aufgerufen hat:

<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>

Am Ende müssen wir ein als ZIP-Datei verpacktes GraalVM Native Image erstellen, das als Lambda Custom Runtime bereitgestellt werden kann mit:


<dependency>
   <groupId>com.formkiq</groupId>
   <artifactId>lambda-runtime-graalvm</artifactId>
   <version>2.3.1</version>
</dependency>
Bereitstellen des nativen GraalVM-Images als benutzerdefinierte Lambda-Laufzeitumgebung

In der AWS SAM-Vorlage stellen wir die Lambda-Laufzeit als

provided.al2023 bereit (die neueste Version der benutzerdefinierten Laufzeit) und stellen den Pfad zum zuvor erstellten GraalVM Native Image function-native-zip bereit. zip.

  <buildArgs>
    --no-fallback
    --enable-http
    -H:ReflectionConfigurationFiles=../src/main/reflect.json
 </buildArgs>
Jetzt sind wir bereit, unsere Anwendung mit

bereitzustellen

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

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

Abschluss

In diesem Teil der Serie haben wir erklärt, wie man AWS Lambda-Funktionen mit einer benutzerdefinierten Laufzeit entwickelt und bereitstellt, die GraalVM Native Image enthält. Im nächsten Teil der Serie messen wir die Kalt- und Warmstartzeiten der Lambda-Funktion für ein solches Szenario für verschiedene Speichereinstellungen der Lambda-Funktion.

Das obige ist der detaillierte Inhalt vonLambda-Funktion mit GraalVM Native Image – Teilweise zum Entwickeln und Bereitstellen einer Lambda-Funktion mit benutzerdefinierter Laufzeit. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn