¡Compártelo!

Introducción a Quarkus: ¿qué es, características y por qué utilizarlo?

En este artículo vamos a conocer Quarkus, una tecnología que permite ejecutar de forma eficiente aplicaciones Java en contenedores Kubernetes. Para entender qué es Quarkus y las ventajas de utilizarlo, analizaremos la evolución de la arquitectura de las aplicaciones Java que nos ha llevado hasta este marco que adapta Java a la computación en la nube. ¡Vamos allá!

Java y JVM

Como sabemos, la arquitectura tradicional de aplicaciones Java está basada en una capa intermedia, la llamada máquina virtual (JVM), que hace las veces de mediador entre la aplicación y el sistema operativo. La JVM interpreta el bytecode Java precompilado en un entorno de hardware y sistema operativo concretos, lo que asegura la portabilidad del código fuente Java original.

Para ello, se ocupa de funciones tales como la reserva del espacio en memoria, la liberación de la memoria no usada (garbage collection), la asignación de variables a registros y pilas, las llamadas al sistema huésped, la planificación de hilos… Esta arquitectura tradicional puede representarse de esta manera:

Arquitectura Java tradicional
Arquitectura Java tradicional. Fuente: Elaboración propia.

Java y Docker

El objetivo de la JVM, decimos, es independizar el código fuente de la máquina concreta que lo ejecuta. Ahora bien, actualmente se ha popularizado otra arquitectura, la orientada a contenedores, gracias a tecnologías como Docker.

En este caso, entre el sistema operativo y las aplicaciones también se establece una capa virtual que logra la independencia respecto a la máquina —como una JVM, pero ahora no sólo respecto a Java, sino a cualquier tipo de tecnología— en la que disponer una serie de contenedores aislados e independientes los unos de los otros.

Así, podemos tener un contendor que ejecute un jar en Java 6, otro con un microservicio en Java 11, otro más con un servidor de aplicaciones. Cada contenedor trabajará con su propia JVM sobre la misma capa Docker. El esquema sería en este caso:

Arquitectura Java basada en contenedores
Arquitectura Java basada en contenedores. Fuente: Elaboración propia.

Java y Cloud

A partir de aquí, se ha evolucionado a la arquitectura con orquestador, en la que ya no solo hablamos de aplicaciones desplegadas en servidores contenedorizados, sino de un cluster de nodos gestionado por un orquestador como Kubernetes.

Esto permite externalizar la gestión de la administración (escalado dinámico de las necesidades de cada aplicación, balanceo de carga, tolerancia a fallos) y centrarse en la lógica de negocio como tal que debe implementar nuestro conjunto de aplicaciones. Este esquema ha favorecido el modelo serverless, en el que accedemos a distintos microservicios y funciones (FaaS) distribuidas para realizar nuestra lógica de negocio.

Arquitectura Java con orquestador
Arquitectura Java con orquestador. Fuente: Elaboración propia.

La idea subyacente del modelo serverless es el bajo consumo: las aplicaciones están detenidas y se arrancan sólo cuando son requeridas; después de realizar su trabajo, liberan recursos y se apagan. Esto conlleva la reducción de costes, dado que sólo se paga por el procesamiento efectivo, en vez de tener una aplicación levantada consumiendo recursos continuamente.

Pero en este modelo es esencial que el tiempo de arranque sea del orden de milisegundos, para que la rapidez de respuesta no se vea afectada. El tiempo de arranque de las aplicaciones Java, de varios segundos, hacía inviable este modelo.

Compilación nativa

Ahora bien, si observamos el segundo diagrama parece claro que, con una capa de virtualización como Docker, las JVMs vienen a ser redundantes. Si la idea de la JVM era que el sistema operativo fuese transparente a la aplicación Java, la cuestión es que esta función está siendo ya cumplida por Docker. En tales casos es posible valorar la conveniencia de eliminar la JVM y compilar cada aplicación Java de forma nativa, para que sea el SO el que se encargue de las tareas que llevaba a cabo la JVM.

La primera ventaja de esta compilación nativa es una reducción drástica del tiempo de inicio de la aplicación. Esto permite algo hasta hace poco impensable: un enfoque serverless de nuestras aplicaciones Java.

¿Qué es Quarkus?

Quarkus es una tecnología que habilita Java como una plataforma efectiva para el actual modelo de arquitectura serverless, de microservicios, funciones como servicio (Faas) y contenedores orquestados. Esto es, para el enfoque de la computación en la nube.

En concreto, el objetivo primario de Quarkus es la ejecución eficiente de aplicaciones Java en contenedores Kubernetes (permite generar automáticamente recursos Kubernetes por defecto y desplegar imágenes de contenedores en un solo paso), tanto para JVMs como para compilación nativa.

Además está pensado para trabajar con estándares, frameworks y librerías Java populares, como Spring (no tanto Spring Boot, que es su competidor directo), Apache Kafka, RESTEasy (JAX-RS), Hibernate ORM (JPA), Camel, etc.

Características de Quarkus

Las características principales de Quarkus son:

  • Tiempos de arranque de aplicaciones muy reducidos (300 veces más rápido que aplicaciones Java tradicionales).
  • Bajo consumo de memoria (1/10 que aplicaciones Java tradicionales).
  • Permite combinar código imperativo y código reactivo (no bloqueante, basado en suscripción).

Por ejemplo, si un microservicio Java tradicional tarda varios segundos en arrancar y utiliza varios cientos de megabytes de memoria, en Quarkus un microservicio similar compilado en nativo tarda del orden de decenas de milisegundos y consume solo unas decenas de megabytes de memoria.

¿Cómo funciona Quarkus?

Para la compilación nativa Quarkus recurre a GraalVM, una máquina virtual de rendimiento optimizado que puede ejecutar código de diferentes lenguajes de programación, no solo los habituales de JVM (Kotlin, Scala, Clojure) sino otros como C++, Python o JavaScript.

En todo caso, no es obligatorio compilar nativamente para obtener una ganancia de eficiencia. Quarkus recurre a la compilación anticipada (ahead-of-time, AOT) para optimizar el jar de modo que arranque rápidamente y con un consumo de RAM menor que un microservicio tradicional sobre JVM.

El siguiente diagrama compara el tiempo de arranque y el consumo de memoria de un microservicio tradicional, otro en Quarkus y otro en Quarkus con compilación nativa:

Comparativa del tiempo de arranque y el consumo de memoria de un microservicio tradicional, otro en Quarkus y otro en Quarkus con compilación nativa
Comparativa del tiempo de arranque y el consumo de memoria de un microservicio tradicional, otro en Quarkus y otro en Quarkus con compilación nativa. Fuente: https://quarkus.io/

Conclusión

Quarkus es un marco muy interesante para implementar Java en Kubernetes. Supone un paso más dentro de la evolución de la arquitectura de aplicaciones Java, que hemos repasado en este artículo.

Concretamente, en este post hemos visto que:

  • La máquina virtual JVM, que permitía la portabilidad de un mismo código fuente a distintas plataformas, se muestra inadecuada para el actual paradigma de computación en la nube.
  • La virtualización mediante contendores aislados de Docker hace posible prescindir de la JVM para el código Java mediante la compilación nativa.
  • Quarkus, mediante el uso de Docker y Kubernetes, logra hacer de Java una tecnología adecuada a la computación en la nube.
  • GraalVM ofrece herramientas de compilación nativa para Quarkus.

En el próximo artículo veremos cómo crear un microservicio sencillo con Quarkus y cómo compilarlo nativamente mediante GraalVM. ¡No te lo pierdas! Mientras tanto, puedes aprender más en nuestro canal de YouTube. ¡Suscríbete!

Si estás pensando en dar el salto al Cloud Computing para acelerar la innovación y reducir costes, en Profile podemos ayudarte. Contacta ahora con nosotros.

Artículos ​ relacionados