Introducción a Quarkus – Parte II

0
311

En este tutorial continuaremos conociendo Quarkus, utilizaremos contenedores y GraalVM para sacar el máximo rendimiento.

Índice de contenidos

1. Introducción

En el anterior tutorial pudimos ver las bondades que nos ofrece Quarkus para el desarrollo de servicios ligeros. Pudimos hacer algunas mediciones y observar si mejoramos algo.En este tutorial nos centraremos en mejorar estos tiempos utilizando la compilación nativa y el uso de contenedores.

Comencemos.

2. Entorno

El tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil MacBook Pro 15 pulgadas (2.3 GHz Intel i9, 32GB 2400 Mhz DDR4, 1 TB Flash Storage).
  • Sistema Operativo: MacOs Catalina 10.15.2
  • Entorno de desarrollo: IntelliJ IDEA 2019.3.1
  • Apache Maven 3.6.3
  • Quarkus 1.1.1.Final
  • GraalVM 19.2.1 C.E (basado en OpenJDK 8)
  • Docker 19.03.5

3. Prerrequistos

Quarkus incorpora en sus guías la documentación necesaria para que podáis instalaros los componentes necesarios. Para este tutorial necesitaremos:

  • Entorno de desarrollo para C
  • Docker
  • GraalVM 19.2

3.1. Entorno de desarrollo para C

Para la compilación nativa hace falta disponer de estas librerías. En el caso de Linux, hace falta un GCC, las librerías glibc y cabeceras zlib.

En el caso de masOS, XCode proporciona las dependencias necesarias.

3.2. Docker

La mayoría de vosotros ya conocéis Docker pero si no fuese el caso, disponéis de estupendos tutoriales en esta misma web.

Instalando un UI simple para Docker

Desarrollo de microservicios con Spring Boot y Docker

Docker for dummies

3.3. GraalVM 19.2

A este apartado podríamos dedicarle un tutorial completo, es un proyecto de Oracle que hasta hace poco (mayo 2019) no ha publicado su primera versión lista para producción. Si bien, es muy amplio, si nos ceñimos a la definición podemos leer:

«GraalVM es una máquina virtual universal para ejecutar aplicaciones escritas en JavaScript, Python, Ruby, R, lenguajes basados en JVM como Java, Scala, Groovy, Kotlin, Clojure y lenguajes basados en LLVM como C y C ++.

GraalVM elimina el aislamiento entre lenguajes de programación y permite la interoperabilidad en un tiempo de ejecución compartido. Puede ejecutarse de forma independiente o en el contexto de OpenJDK, Node.js u Oracle Database.»

Actualmente se habla mucho de GraalVM y no es para menos ya que muchos lenguajes, frameworks se hayan adherido y tienen actualmente soporte para la misma.

Al ser un producto dependiente del entorno en que se ejecuta, hay diferentes versiones. En nuestro caso hemos instalado la versión de macOS para una openJDK 8. Disponéis de una completa documentación sobre su instalación en su web.

4. Probando Quarkus y GraalVM

Vamos a probar de nuevo nuestro servicio con Quarkus pero utilizando GraalVm para observar la posible mejora. En este caso, no hace falta que realicemos modificaciones en nuestro servicio, basta con apuntar a la nueva máquina virtual.

Arranque con GraalVM

Tiempo de la primera petición con GraalVM

Como podemos ver, los tiempos con respecto al tutorial anterior se ha reducido un poco más sin tocar nuestro componente jar. Vamos a incorporar la compilación nativa en esta ecuación para sacarle el máximo provecho al hardware que tenemos.

5. Quarkus con compilación nativa

Aprovechando las posibilidades que proporciona GraalVM y Quarkus vamos a ejecutar nuestro servicio de forma nativa.

En este caso, el plugin de Quarkus ha incluido una fase adicional para el compilado nativo y los tiempos de compilación se han incrementado. En la carpeta target, ahora podéis observar cómo ha creado un nuevo ejecutable que incorpora todo lo necesario para la ejecución de nuestro servicio REST. Al ejecutarlo se puede observar:

Arranque con compilación nativa

Como veis, los tiempos ahora son realmente bajos. Esto se debe a que es un ejecutable nativo al entorno, en este caso para mac. Este enfoque tiene la pequeña pega que no es portable entre entornos (nuestros servidores pueden estar en cualquier plataforma). Aquí es donde entra en acción el soporte a contenedores.

6. Juntemos todo a ver qué pasa

Hasta ahora hemos probado cada herramienta de forma independiente para ver lo que nos aporta cada una de ellas. Ahora vamos a preparar una versión nativa para un contenedor de docker y juntar todas las piezas.

Este paquetizado genera un ejecutable nativo para linux de 64 bits. Esto no supone un problema porque a continuación se va a transferir a un contenedor docker que contiene una imagen de linux que “entiende” este ejecutable.

Por último arrancamos nuestro contenedor con nuestra API REST.

Tiempo de arranque de la versión “dockerizada”

Tiempo de la primera petición al servicio

Como se puede observar los tiempos son muy bajos, nuestro servicio está “dockerizado” y es un ejecutable nativo para la imagen docker.

Si atendemos al tiempo de primera petición y tamaño también son muy bajos. El tamaño de la imagen docker también es muy bajo.

7. Conclusiones

La combinación de todas estas tecnologías nos están llevando hacia servicios cada vez más ligeros y optimizados en un contexto de contenedores. Aún están en una fase temprana porque acaban de sacar las primeras versiones para un entorno productivo pero habrá que estar atentos a su futura evolución.

Espero que os sea de utilidad.

8. Referencias

Dejar respuesta

Please enter your comment!
Please enter your name here