[JAVA] Erste Schritte mit Micronaut 2.x ~ Native Build und Bereitstellung für AWS Lambda ~

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.

Umgebung

Erstellen Sie eine Anwendung für die Lambda-Funktion mit Micronaut

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

Schauen wir uns die erstellte Datei an

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

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.

BookSaved.java


package native.lambda
import io.micronaut.core.annotation.Introspected

@Introspected
class BookSaved {
    var name: String? = null
    var isbn: String? = null
}

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.

Erstellen einer Lambda-Funktion

Wir werden mit den Vorbereitungen fortfahren, um die mit Micronaut erstellte Anwendung zu erhöhen.

1. Melden Sie sich bei der AWS-Konsole an

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.

2. Erstellen Sie Lambda

Ö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. create-lambda-function.png Micronaut ist eine Java-App, aber für nativ erstellte Anwendungen wählen Sie für Ihre Laufzeit "Ihren eigenen Bootstrap" anstelle von Java.

Grundeinstellungen ändern

Bearbeiten Sie die Grundeinstellungen auf dem Bildschirm, nachdem Sie Lambda erstellt haben. lambda-info-setting.png

Nehmen Sie die folgenden Änderungen über die Schaltfläche Bearbeiten oben rechts vor.

lambda-info-setting-datail.png du sparst.

Ein natives Bild erstellen

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

Erstellen Sie eine Datei für die Bereitstellung

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

Auf Lambda hochladen

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. lambda-upload.png

Bewegen wir Lambda

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!\"}"
}

test-event.png Drücken Sie "Test", wenn die Einstellungen abgeschlossen sind. Sehen wir uns das Ergebnis der Protokollausgabe unten an. mn-lambda-native.png 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!

Bonus

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. mn-lambda-normal.png 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 **.

Zusammenfassung

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.

Verweise

Dieser Artikel wurde unter Bezugnahme auf die folgenden Informationen verfasst.

Recommended Posts

Erste Schritte mit Micronaut 2.x ~ Native Build und Bereitstellung für AWS Lambda ~
Erstellen Sie AWS Lambda mit Quarkus
Wie kann ich mit NUXTJS Official S3 und CloudFront für AWS bereitstellen? Mit Docker-Compose
Erste Schritte mit Java_Kapitel 8_Über "Instanzen" und "Klassen"
Stellen Sie Rails mit AWS Copilot für ECS Fargate bereit
Erste Schritte mit Kotlin zum Senden an Java-Entwickler
So erstellen Sie eine API mit GraphQL und Rails
Erste Schritte mit Doma-Einführung in die Kriterien-API
Zurück zum Anfang und erste Schritte mit Java ① Datentypen und Zugriffsmodifikatoren
Ich habe MySQL 5.7 mit Docker-Compose gestartet und versucht, eine Verbindung herzustellen
Erste Schritte mit älteren Java-Ingenieuren (Stream + Lambda)
Erste Schritte mit DBUnit
Erste Schritte mit Ruby
Erste Schritte mit Swift
Erste Schritte mit Doma-Transaktionen
Erste Schritte mit Java und Erstellen eines Ascii Doc-Editors mit JavaFX
Verwenden Sie Java, das in Android Studio enthalten ist, um React Native zu erstellen
Erste Schritte mit der Verarbeitung von Doma-Annotationen
Erste Schritte mit Java Collection
Erste Schritte mit JSP & Servlet
Erste Schritte mit Java Basics
Erste Schritte mit Spring Boot
Erste Schritte mit Ruby-Modulen
Zurück zum Anfang, Erste Schritte mit Java ② Steueranweisungen, Schleifenanweisungen
Versuchen Sie, SlackBot mit Ruby x Sinatra auf AWS Lambda auszuführen
Erstellen Sie ein periodisches Programm mit Ruby x AWS Lambda x CloudWatch-Ereignissen