[JAVA] Premiers pas avec Micronaut 2.x ~ Construction native et déploiement sur AWS Lambda ~

Dernière fois: après Introduction à Micronaut 2.x, cette fois, nous téléchargerons l'application Micronaut native sur AWS Lambda.

J'étais un peu confus parce que les applications de fonction créées au début après la version 2.0 ont considérablement changé, mais comme le blog officiel contient des instructions détaillées sur la façon de le créer, je vais le créer en fonction de cela.

environnement

Créer une application pour la fonction Lambda avec Micronaut

Créer un répertoire de travail

$ mkdir 02-native-function && cd 02-native-function

Nous allons le créer en utilisant la CLI Micronaut. Cette fois, nous utiliserons Java comme langage.

#Créer une application de fonction avec CLI
$ mn create-function-app example.micronaut.complete --features=aws-lambda,graalvm

#Vérification
$ 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

#Déplacer vers le dossier de l'application
$ cd complete

Regardons le fichier créé

Les 4 fichiers suivants seront créés dans src / main / java / example / micronaut /.

Regardons maintenant le contenu du fichier un par un.

[Book.java] Une classe de modèle pour stocker l'entrée.

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

Je ne suis pas sûr, mais est-ce comme une classe de réception pour passer des appels Lambda à partir d'API Gateway pour voir le contenu du code source? Lors de la création d'événements de hook Lambda pour S3, les génériques de ʻAbstractMicronautLambdaRuntime` peuvent être pour S3.

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

Reçoit la valeur d'entrée de l'API dans Book.java, emballe la valeur de retour dans BookSaved.java et la renvoie.

Créer une fonction Lambda

Nous allons procéder aux préparatifs pour monter l'application créée avec Micronaut.

1. Connectez-vous à la console AWS

Connectez-vous à la AWS Console. Si vous n'en avez pas encore créé, créez un compte AWS, puis revenez ici.

2. Créez Lambda

Une fois connecté, ouvrez Services> Lambda. Appuyez sur [Créer une fonction] en haut à droite de l'écran.

Sélectionnons et entrons comme suit. create-lambda-function.png Micronaut est une application Java, mais pour les applications natives, choisissez "votre propre bootstrap" au lieu de Java pour votre runtime.

Modifier les paramètres de base

Modifiez les paramètres de base à l'écran après avoir créé Lambda. lambda-info-setting.png

Apportez les modifications suivantes à partir du bouton Modifier en haut à droite.

lambda-info-setting-datail.png vous sauvegardez.

Créer une image native

En ajoutant --features = graalvm lors de la création avec CLI, un fichier pour la construction native est créé.

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

Créer un fichier pour le déploiement

Utilisez deploy.sh pour exécuter Dockerfile pour créer des artefacts pour les versions natives. (C'est peut-être mon problème de réseau, mais cela a pris du temps ...)

$ 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
 ...
 
 #Le fichier est créé sous build
 $ ls build
 function.zip

Transférer vers Lambda

Téléchargez le fichier déployé sur Lambda. Ouvrons la fonction Lambda créée ci-dessus.

Appuyez sur Action dans le code de fonction, appuyez sur Télécharger le fichier .zip et sélectionnez le function.zip que vous venez de créer pour le télécharger. lambda-upload.png

Déplaçons Lambda

Tout d'abord, créez un événement de test pour le faire fonctionner. Appuyez sur "Set Test Event" ci-dessus et réglez comme suit.

bookTest


{
  "body": "{\"name\":\"Book Test!\"}"
}

test-event.png Appuyez sur "Test" lorsque les paramètres sont terminés. Voyons le résultat de la sortie du journal en bas. mn-lambda-native.png Init Duration: 450.70 ms Duration: 189.76 ms

La durée d'initialisation est l'heure de démarrage et la durée est le temps de traitement. Vous pouvez voir qu'il est très rapide car le temps de démarrage est de 0,45 seconde.

C'est impressionnant d'avoir cette fois avec une application créée à partir de Java, ce qui est un démarrage à froid!

prime

Regardons la vitesse d'exécution dans une application déployée avec un fichier Jar normal au lieu d'une construction native. J'omettrai l'endroit pour créer et télécharger. mn-lambda-normal.png Init Duration: 2909.91 ms Le temps de démarrage initial est d'environ 3 secondes.

La différence avec la version native est ** d'environ 2,5 secondes **.

Résumé

J'ai pu confirmer que je pouvais facilement accéder à AWS Lambda! Vous pouvez facilement créer un fichier de déploiement car Dockerfile et deploy.sh pour le téléchargement sont générés simplement en créant une application via CLI. J'ai pu constater que la vitesse de démarrage est également beaucoup plus rapide qu'avec Java normal.

La prochaine fois, j'aimerais créer une application Web qui se connecte à la base de données avec Micronaut et la traite.

Les références

Cet article a été rédigé en référence aux informations suivantes.

Recommended Posts

Premiers pas avec Micronaut 2.x ~ Construction native et déploiement sur AWS Lambda ~
Créez AWS Lambda avec Quarkus
Comment déployer sur AWS à l'aide de NUXTJS S3 et CloudFront officiels? Avec docker-compose
Premiers pas avec Java_Chapter 8_A propos des "Instances" et des "Classes"
Déployer des rails sur ECS Fargate avec AWS Copilot
Premiers pas avec Kotlin à envoyer aux développeurs Java
Comment créer une API avec GraphQL et Rails
Premiers pas avec Doma - Introduction à l'API Criteria
Revenir au début et démarrer avec Java ① Types de données et modificateurs d'accès
J'ai démarré MySQL 5.7 avec docker-compose et j'ai essayé de me connecter
Premiers pas avec les anciens ingénieurs Java (Stream + Lambda)
Premiers pas avec DBUnit
Premiers pas avec Ruby
Premiers pas avec Swift
Premiers pas avec Doma-Transactions
Premiers pas avec Java et création d'un éditeur Ascii Doc avec JavaFX
Utilisez Java inclus avec Android Studio pour créer React Native
Premiers pas avec le traitement Doma-Annotation
Premiers pas avec Java Collection
Premiers pas avec JSP et servlet
Premiers pas avec les bases de Java
Premiers pas avec Spring Boot
Premiers pas avec les modules Ruby
Revenir au début, démarrer avec Java ② Instructions de contrôle, instructions de boucle
Essayez d'exécuter SlackBot réalisé avec Ruby x Sinatra sur AWS Lambda
Créer un programme périodique avec Ruby x AWS Lambda x CloudWatch Events