La possibilità di incrementare le prestazioni di un microservizio in termini di tempi di risposta anche di pochi millisecondi è un aspetto rilevante. Si pensi ad ambienti cloud come AWS dove un cliente paga in base all'uso delle risorse assegnate.
In tale contesto, quando ad un'applicazione accedono milioni di utenti, il tempo di risposta di un servizio fa sentire il suo peso moltiplicando i costi. La possibilità di ridurre questo tempo, ottimizzando il consumo di risorse di un microservizio, diventa un fattore non solo di ottimizzazione software ma anche di abbattimento dei costi aziendali.
Il packaging and deploying di un microservizio Java è stato implicitamente descritto negli articoli precedenti, ora vedremo come Quarkus consenta la compilazione in codice nativo di un microservizio per ottimizzarne la rapidità di risposta.
GraalVM
GraalVM è un runtime ad alte performance che include una Universal Virtual Machine a runtime condiviso.
I linguaggi supportati sono JavaScript, Python, Ruby, R, linguaggi JVM-based come Java, Scala, Kotlin, e linguaggi LLVM-based come C e C++.
GraalVM può essere eseguito in un contesto OpenJDK per rendere più veloci applicazioni Java, come i microservizi, utilizzando anche una compilazione just in time.
Consideriamo come riferimento un'installazione di Ubuntu al fine di mostrare i passaggi d'installazione e configurazione di questo ambiente.
Una volta scaricato il file e posizionato in una nostra directory, eseguiamo i seguenti comandi da terminale per decomprimere il file stesso e configurare l'ambiente:
sudo apt-get install build-essential libz-dev zlib1g-dev
tar -xzf graalvm-ce-java11-linux-amd64-21.0.0.tar.gz
export GRAALVM_HOME=/home/osboxes/Quarkus/graalvm-ce-java11-21.0.0
export JAVA_HOME=/home/osboxes/Quarkus/graalvm-ce-java11-21.0.0
export PATH=/home/osboxes/Quarkus/graalvm-ce-java11-21.0.0/bin:$PATH
avendo come riferimento il percorso d'esempio /home/osboxes/Quarkus
in cui è stato decompresso il file graalvm-ce-java11-linux-amd64-21.0.0.tar.gz
.
La prima esecuzione della lista precedente si rende necessaria per assicurare la presenza del compilatore GCC e delle librerie glibc e zlib headers.
I comandi eseguiti hanno effetto solo all'interno del terminale corrente. Possiamo renderli permanenti agendo su Linux ricevendo cosi, come ulteriore beneficio, la possibilità di eseguire, all'interno di IntelliJ, il comando maven di generazione dell'immagine nativa.
Concludiamo questa fase con l'installazione dell'ambiente:
./gu install native-image
eseguito all'interno della directory /home/osboxes/Quarkus/graalvm-ce-java11-21.0.0/bin
della nostra installazione di GraalVM.
Immagine nativa del microservizio
Vediamo ora come realizzare un'immagine nativa del microservizio relativo al convertitore di valuta creato negli articoli precedenti. Da terminale posizioniamoci nella directory contenente il file pom del progetto ed eseguiamo il comando maven:
./mvnw package -Pnative
maven inizierà la generazione del codice nativo del nostro microservizio. Nella figura che segue mostriamo la fase finale del processo:
ispezionando la directory target del progetto noteremo la generazione del file code-with-quarkus-1.0.0-SNAPSHOT-runner
, esso è il risultato
della generazione in codice nativo Linux del microservizio.
possiamo eseguire il microservizio dall'interno della directory target del progetto lanciando successivamente il comando ./code-with-quarkus-1.0.0-SNAPSHOT-runner
.
Conclusioni
Abbiamo visto come si possa generare un'immagine in codice nativo di un microservizio in Java tramite l'installazione di un ambiente
GraalVM. Se si sviluppa in un ambiente a container tale requisito non è più indispensabile in quanto con Quarkus si può realizzare microservizi utilizzando immagini Docker in cui è già configurato l'ambiente GraalVM. Questo argomento esula però dagli obiettivi della guida, ragion per cui non viene ulteriormente approfondito