Letztes Mal: Nach Einführung in Micronaut 2.x werden wir dieses Mal die nativ erstellte Micronaut-App auf AWS Lambda hochladen.
Ich war ein wenig verwirrt, weil sich die Funktions-Apps, die in den frühen Stadien nach Version 2.0 erstellt wurden, erheblich geändert haben. Da der offizielle Blog jedoch detaillierte Anweisungen zur Erstellung enthält, werde ich sie auf dieser Grundlage erstellen.
Erstellen Sie ein Arbeitsverzeichnis
$ mkdir 02-native-function && cd 02-native-function
Wir werden es mit der Micronaut CLI erstellen. Dieses Mal werden wir Java als Sprache verwenden.
#Erstellen Sie eine Funktions-App mit CLI
$ mn create-function-app example.micronaut.complete --features=aws-lambda,graalvm
#Bestätigung
$ tree complete
complete/
├── Dockerfile
├── README.md
├── bootstrap
├── build.gradle
├── deploy.sh
├── docker-build.sh
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── micronaut-cli.yml
├── settings.gradle
└── src
├── main
│ ├── java
│ │ └── example
│ │ └── micronaut
│ │ ├── Book.java
│ │ ├── BookLambdaRuntime.java
│ │ ├── BookRequestHandler.java
│ │ └── BookSaved.java
│ └── resources
│ ├── META-INF
│ │ └── native-image
│ │ └── example.micronaut
│ │ └── complete-application
│ │ └── native-image.properties
│ ├── application.yml
│ └── logback.xml
└── test
└── java
└── example
└── micronaut
└── BookRequestHandlerTest.java
16 directories, 21 files
#Wechseln Sie in den Anwendungsordner
$ cd complete
Die folgenden 4 Dateien werden in src / main / java / example / micronaut / erstellt.
Schauen wir uns nun den Inhalt der Datei einzeln an.
[Book.java]
Eine Modellklasse zum Speichern von Eingaben.
Book.java
package example.micronaut;
import edu.umd.cs.findbugs.annotations.NonNull;
import io.micronaut.core.annotation.Introspected;
import javax.validation.constraints.NotBlank;
@Introspected
public class Book {
@NonNull
@NotBlank
private String name;
public Book() {
}
@NonNull
public String getName() {
return name;
}
public void setName(@NonNull String name) {
this.name = name;
}
}
java:BookLambdaRuntime.java
BookLambdaRuntime.java
package example.micronaut;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
import io.micronaut.function.aws.runtime.AbstractMicronautLambdaRuntime;
import java.net.MalformedURLException;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import edu.umd.cs.findbugs.annotations.Nullable;
public class BookLambdaRuntime extends AbstractMicronautLambdaRuntime<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent, Book, BookSaved> {
public static void main(String[] args) {
try {
new BookLambdaRuntime().run(args);
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
@Override
@Nullable
protected RequestHandler<Book, BookSaved> createRequestHandler(String... args) {
return new BookRequestHandler();
}
}
Ich bin mir nicht sicher, aber ist es wie eine Empfangsklasse für Lambda-Aufrufe vom API-Gateway, um den Inhalt des Quellcodes anzuzeigen? Beim Erstellen von Lambda für S3-Hook-Ereignisse können die Generika von "AbstractMicronautLambdaRuntime" für S3 gelten.
[java:BookSaved.java]
BookSaved.java
package native.lambda
import io.micronaut.core.annotation.Introspected
@Introspected
class BookSaved {
var name: String? = null
var isbn: String? = null
}
[java:BookRequestHandler.java]
BookRequestHandler.java
package example.micronaut;
import io.micronaut.core.annotation.Introspected;
import io.micronaut.function.aws.MicronautRequestHandler;
import java.util.UUID;
@Introspected
public class BookRequestHandler extends MicronautRequestHandler<Book, BookSaved> {
@Override
public BookSaved execute(Book input) {
BookSaved bookSaved = new BookSaved();
bookSaved.setName(input.getName());
bookSaved.setIsbn(UUID.randomUUID().toString());
return bookSaved;
}
}
Empfängt den API-Eingabewert in "Book.java", packt den Rückgabewert in "BookSaved.java" und gibt ihn zurück.
Wir werden mit den Vorbereitungen fortfahren, um die mit Micronaut erstellte Anwendung zu erhöhen.
Melden Sie sich bei der [AWS Console] an (https://aws.amazon.com/jp/). Wenn Sie noch kein Konto erstellt haben, erstellen Sie bitte ein AWS-Konto und kehren Sie dann erneut hierher zurück.
Öffnen Sie nach dem Anmelden Services> Lambda
.
Drücken Sie oben rechts auf dem Bildschirm auf [Funktion erstellen].
Lassen Sie uns wie folgt auswählen und eingeben. Micronaut ist eine Java-App, aber für nativ erstellte Anwendungen wählen Sie für Ihre Laufzeit "Ihren eigenen Bootstrap" anstelle von Java.
Bearbeiten Sie die Grundeinstellungen auf dem Bildschirm, nachdem Sie Lambda erstellt haben.
Nehmen Sie die folgenden Änderungen über die Schaltfläche Bearbeiten oben rechts vor.
du sparst.
Durch Hinzufügen von "--features = graalvm" beim Erstellen mit CLI wird eine Datei für den nativen Build erstellt.
Dockerfile
FROM gradle:6.3.0-jdk11 as builder
COPY --chown=gradle:gradle . /home/application
WORKDIR /home/application
RUN ./gradlew build --no-daemon
FROM amazonlinux:2018.03.0.20191014.0 as graalvm
ENV LANG=en_US.UTF-8
RUN yum install -y gcc gcc-c++ libc6-dev zlib1g-dev curl bash zlib zlib-devel zip
ENV GRAAL_VERSION 20.1.0
ENV JDK_VERSION java11
ENV GRAAL_FILENAME graalvm-ce-${JDK_VERSION}-linux-amd64-${GRAAL_VERSION}.tar.gz
RUN curl -4 -L https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-${GRAAL_VERSION}/${GRAAL_FILENAME} -o /tmp/${GRAAL_FILENAME}
RUN tar -zxvf /tmp/${GRAAL_FILENAME} -C /tmp \
&& mv /tmp/graalvm-ce-${JDK_VERSION}-${GRAAL_VERSION} /usr/lib/graalvm
RUN rm -rf /tmp/*
CMD ["/usr/lib/graalvm/bin/native-image"]
FROM graalvm
COPY --from=builder /home/application/ /home/application/
WORKDIR /home/application
RUN /usr/lib/graalvm/bin/gu install native-image
RUN /usr/lib/graalvm/bin/native-image --no-server -cp build/libs/complete-*-all.jar
RUN chmod 777 bootstrap
RUN chmod 777 complete
RUN zip -j function.zip bootstrap complete
EXPOSE 8080
ENTRYPOINT ["/home/application/complete"]
deploy.sh
#!/bin/bash
docker build . -t complete
mkdir -p build
docker run --rm --entrypoint cat complete /home/application/function.zip > build/function.zip
Verwenden Sie deploy.sh
, um Dockerfile
auszuführen und Artefakte für native Builds zu erstellen.
(Vielleicht ist es mein Netzwerkproblem, aber es hat lange gedauert ...)
$ sh ./deploy.sh
Sending build context to Docker daemon 17.63MB
Step 1/24 : FROM gradle:6.3.0-jdk11 as builder
---> 0290cb9c9a7b
Step 2/24 : COPY --chown=gradle:gradle . /home/application
---> 287bbae39066
...
#Die Datei wird unter Build erstellt
$ ls build
function.zip
Laden Sie die bereitgestellte Datei auf Lambda hoch. Öffnen wir die oben erstellte Lambda-Funktion.
Drücken Sie die Aktion im Funktionscode, drücken Sie die ZIP-Datei hochladen und wählen Sie die gerade zum Hochladen erstellte Funktion.zip aus.
Erstellen Sie zunächst ein Testereignis, damit es funktioniert. Drücken Sie oben auf "Set Test Event" und stellen Sie wie folgt ein.
bookTest
{
"body": "{\"name\":\"Book Test!\"}"
}
Drücken Sie "Test", wenn die Einstellungen abgeschlossen sind. Sehen wir uns das Ergebnis der Protokollausgabe unten an. Init Duration: 450.70 ms Duration: 189.76 ms
Die Anfangsdauer ist die Startzeit und die Dauer ist die Verarbeitungszeit. Sie können sehen, dass es sehr schnell ist, da die Startzeit 0,45 Sekunden beträgt.
Es ist beeindruckend, diese Zeit mit einer auf Java basierenden Anwendung zu haben, was ein Kaltstart ist!
Schauen wir uns die Ausführungsgeschwindigkeit in einer Anwendung an, die mit einer regulären Jar-Datei anstelle eines nativen Builds bereitgestellt wird. Ich werde den Ort zum Erstellen und Hochladen weglassen. Init Duration: 2909.91 ms Die anfängliche Startzeit beträgt ca. 3 Sekunden.
Der Unterschied zum nativen Build beträgt ** ca. 2,5 Sekunden **.
Ich konnte bestätigen, dass ich problemlos zu AWS Lambda gelangen konnte! Durch einfaches Erstellen einer Anwendung über die CLI werden "Dockerfile" und "deploy.sh" zum Hochladen generiert, sodass Sie problemlos eine Bereitstellungsdatei erstellen können. Ich konnte feststellen, dass die Startgeschwindigkeit auch viel schneller ist als mit normalem Java.
Beim nächsten Mal möchte ich eine Webanwendung erstellen, die mit Micronaut eine Verbindung zur Datenbank herstellt und diese verarbeitet.
Dieser Artikel wurde unter Bezugnahme auf die folgenden Informationen verfasst.
Recommended Posts