Guida a QuarkusIO

1. Introduzione

Al giorno d'oggi, è molto comune scrivere un'applicazione e distribuirla nel cloud senza preoccuparsi dell'infrastruttura. Serverless e FaaS sono diventati molto popolari.

In questo tipo di ambiente, in cui le istanze vengono create e distrutte frequentemente, il tempo di avvio e il tempo di prima richiesta sono estremamente importanti, in quanto possono creare un'esperienza utente completamente diversa.

Linguaggi come JavaScript e Python sono sempre al centro dell'attenzione in questo tipo di scenario. In altre parole, Java con i suoi vasti JAR e il lungo tempo di avvio non è mai stato uno dei migliori concorrenti.

In questo tutorial, presenteremo Quarkus e discuteremo se è un'alternativa per portare Java in modo più efficace nel cloud .

2. QuarkusIO

QuarkusIO, il Java subatomico supersonico, promette di fornire piccoli artefatti, tempi di avvio estremamente rapidi e tempi di prima richiesta inferiori. Quando combinato con GraalVM, Quarkus compilerà prima del tempo (AOT).

E poiché Quarkus è costruito sulla base degli standard, non abbiamo bisogno di imparare nulla di nuovo. Di conseguenza, possiamo usare CDI e JAX-RS, tra gli altri. Inoltre, Quarkus ha molte estensioni, comprese quelle che supportano Hibernate, Kafka, OpenShift, Kubernetes e Vert.x.

3. La nostra prima applicazione

Il modo più semplice per creare un nuovo progetto Quarkus è aprire un terminale e digitare:

mvn io.quarkus:quarkus-maven-plugin:0.13.1:create \ -DprojectGroupId=com.baeldung.quarkus \ -DprojectArtifactId=quarkus-project \ -DclassName="com.baeldung.quarkus.HelloResource" \ -Dpath="/hello"

Questo genererà lo scheletro del progetto, un HelloResource con un endpoint / hello esposto, configurazione, progetto Maven e Dockerfiles.

Una volta importato nel nostro IDE, avremo una struttura simile a quella mostrata nell'immagine sottostante:

Esaminiamo il contenuto della classe HelloResource :

@Path("/hello") public class HelloResource { @GET @Produces(MediaType.TEXT_PLAIN) public String hello() { return "hello"; } }

Finora sembra tutto a posto. A questo punto, abbiamo una semplice applicazione con un unico endpoint RESTEasy JAX-RS. Andiamo avanti e testiamolo aprendo un terminale ed eseguendo il comando:

./mvnw compile quarkus:dev:

Il nostro endpoint REST dovrebbe essere esposto in localhost: 8080 / hello. Proviamolo con il comando curl :

$ curl localhost:8080/hello hello

4. Ricarica a caldo

Quando viene eseguito in modalità di sviluppo ( ./mvn compile quarkus: dev ), Quarkus fornisce una funzionalità di ricarica rapida. In altre parole, le modifiche apportate ai file Java o ai file di configurazione verranno automaticamente compilate una volta aggiornato il browser . La caratteristica più impressionante qui è che non abbiamo bisogno di salvare i nostri file. Questo potrebbe essere buono o cattivo, a seconda delle nostre preferenze.

Modificheremo ora il nostro esempio per dimostrare la capacità di ricarica a caldo. Se l'applicazione viene arrestata, possiamo semplicemente riavviarla in modalità sviluppatore. Useremo lo stesso esempio di prima come punto di partenza.

Innanzitutto, creeremo una classe HelloService :

@ApplicationScoped public class HelloService { public String politeHello(String name){ return "Hello Mr/Mrs " + name; } }

Ora modificheremo la classe HelloResource , iniettando HelloService e aggiungendo un nuovo metodo:

@Inject HelloService helloService; @GET @Produces(MediaType.APPLICATION_JSON) @Path("/polite/{name}") public String greeting(@PathParam("name") String name) { return helloService.politeHello(name); }

Successivamente, testiamo il nostro nuovo endpoint:

$ curl localhost:8080/hello/polite/Baeldung Hello Mr/Mrs Baeldung

Apporteremo un'altra modifica per dimostrare che lo stesso può essere applicato ai file delle proprietà. Modifica di lasciare che l'application.properties di file e aggiungere una chiave di più:

greeting=Good morning

Dopodiché, modificheremo HelloService per utilizzare la nostra nuova proprietà:

@ConfigProperty(name = "greeting") private String greeting; public String politeHello(String name){ return greeting + " " + name; }

Se eseguiamo lo stesso comando curl , ora dovremmo vedere:

Good morning Baeldung

Possiamo facilmente creare un pacchetto dell'applicazione eseguendo:

./mvnw package 

Questo genererà 2 file jar all'interno della directory di destinazione :

  • quarkus-project-1.0-SNAPSHOT-runner.jar - un jar eseguibile con le dipendenze copiate in target / lib
  • quarkus-project-1.0-SNAPSHOT.jar - contiene classi e file di risorse

Ora possiamo eseguire l'applicazione in pacchetto:

java -jar target/quarkus-project-1.0-SNAPSHOT-runner.jar

5. Immagine nativa

Successivamente, produrremo un'immagine nativa della nostra applicazione. Un'immagine nativa migliorerà il tempo di avvio e il tempo per la prima risposta. In altre parole, contiene tutto ciò di cui ha bisogno per essere eseguito, inclusa la JVM minima necessaria per eseguire l'applicazione .

Per cominciare, dobbiamo avere GraalVM installato e la variabile d'ambiente GRAALVM_HOME configurata.

Ora fermeremo l'applicazione (Ctrl + C), se non è già stata arrestata, ed eseguiremo il comando:

./mvnw package -Pnative

Questo può richiedere alcuni secondi per completare. Poiché le immagini native cercano di creare tutto il codice AOT per avviarsi più velocemente, di conseguenza avremo tempi di compilazione più lunghi.

We can run ./mvnw verify -Pnative to verify that our native artifact was properly constructed:

Secondly, we'll create a container image using our native executable. For that, we must have a container runtime (i.e. Docker) running in our machine. Let's open up a terminal window and execute:

./mvnw package -Pnative -Dnative-image.docker-build=true 

This will create a Linux 64-bit executable, therefore if we're using a different OS, it might not be runnable anymore. That's okay for now.

The project generation created a Dockerfile.native for us:

FROM registry.fedoraproject.org/fedora-minimal WORKDIR /work/ COPY target/*-runner /work/application RUN chmod 775 /work EXPOSE 8080 CMD ["./application", "-Dquarkus.http.host=0.0.0.0"] 

If we examine the file, we have a hint at what comes next. First, we'll create a docker image:

docker build -f src/main/docker/Dockerfile.native -t quarkus/quarkus-project .

Now, we can run the container using:

docker run -i --rm -p 8080:8080 quarkus/quarkus-project

The container started in an incredibly low time of 0.009s. That's one of the strengths of Quarkus.

Finally, we should test our modified REST to validate our application:

$ curl localhost:8080/hello/polite/Baeldung Good morning Baeldung

6. Deploying to OpenShift

Once we're done testing locally using Docker, we'll deploy our container to OpenShift. Assuming we have the Docker image on our registry, we can deploy the application following the steps below:

oc new-build --binary --name=quarkus-project -l app=quarkus-project oc patch bc/quarkus-project -p '{"spec":{"strategy":{"dockerStrategy":{"dockerfilePath":"src/main/docker/Dockerfile.native"}}}}' oc start-build quarkus-project --from-dir=. --follow oc new-app --image-stream=quarkus-project:latest oc expose service quarkus-project

Now, we can get the application URL by running:

oc get route

Lastly, we'll access the same endpoint (note that the URL might be different, depending on our IP address):

$ curl //quarkus-project-myproject.192.168.64.2.nip.io/hello/polite/Baeldung Good morning Baeldung

7. Conclusion

In questo articolo, abbiamo dimostrato che Quarkus è un'ottima aggiunta che può portare Java in modo più efficace nel cloud. Ad esempio, ora è possibile immaginare Java su AWS Lambda. Inoltre, Quarkus si basa su standard come JPA e JAX / RS. Pertanto, non abbiamo bisogno di imparare nulla di nuovo.

Quarkus ha attirato molta attenzione ultimamente e molte nuove funzionalità vengono aggiunte ogni giorno. Ci sono diversi progetti di avvio rapido per provare Quarkus nel repository Quarkus GitHub.

Come sempre, il codice per questo articolo è disponibile su GitHub. Buona programmazione!