8 marcos Java para un mundo nativo de la nube

Estos marcos Java más livianos combinan la flexibilidad nativa de la nube con la ingeniería comprobada de Java, para que pueda escribir código receptivo que sea fácil de implementar en cualquier lugar.

Una red de nubes con código binario.
Thinkstock

El lenguaje de programación Java está bien entrado en su tercera década, y el lenguaje y su código de bytes han encontrado un hogar en todo, desde chips integrados hasta granjas de servidores masivas. La combinación de Java de una máquina virtual sólida como una roca y una gran colección de bibliotecas crea un ecosistema fértil para escribir código que se ejecuta en todas partes.

Sin embargo, un área en la que Java ha tenido problemas es el mundo de los servidores, que a menudo deben hacer malabarismos con las conexiones de miles o incluso millones de usuarios. En los primeros años, las herramientas de Java estaban entre las mejores para crear aplicaciones del lado del servidor que aplicaban la lógica comercial para todos los usuarios. Los marcos de Java como J2EE, Hibernate, Spring y el modelo básico de servlets de Java hicieron que la creación de aplicaciones web sólidas fuera relativamente fácil.

La tecnología prosperó hasta que aparecieron JavaScript y Node.js. Node.js atrajo mucha atención y los desarrolladores comenzaron a migrar al entorno de tiempo de ejecución de JavaScript. En general, hubo dos razones: primero, los desarrolladores agradecieron la oportunidad de ejecutar el mismo código en el servidor y en un cliente de navegador. En segundo lugar, los servidores Node.js a menudo brindaban un rendimiento mucho más rápido, gracias a su modelo reactivo .

El ecosistema de Java se adaptó para competir. Para empezar, algunos desarrolladores adoptaron herramientas como Google Web Toolkit , que traduce Java a JavaScript. Luego, trabajaron para acelerar Java en el servidor. Los primeros marcos de trabajo de Java para el servidor tenían una limitación: cada solicitud entrante tenía su propio hilo. Esta era una forma limpia de organizar los datos entrantes y salientes, pero también era agotador. La creación de un hilo requiere miles de bytes de sobrecarga, lo que podría limitar la cantidad de usuarios que cada servidor puede manejar. Node.js usó un modelo diferente que le permitió hacer malabarismos con muchos más usuarios sin esta sobrecarga.

Más recientemente, los desarrolladores de Java han llevado innovaciones de Node.js a la pila de Java, en particular los marcos de Java nativos de la nube. Estos marcos imitan el enfoque de Node.js y admiten funciones livianas que se ejecutan en máquinas en la nube y pueden iniciarse y detenerse rápidamente. Prescinden de bibliotecas adicionales para admitir una implementación rápida en las instancias de servidor más delgadas disponibles. Los marcos Java nativos de la nube están diseñados para admitir constelaciones de microservicios que se pueden instalar y reiniciar de forma independiente. Por lo general, se envían en contenedores como Docker o Podman para compilaciones e instalaciones lo más rápidas posibles.

Los desarrolladores modernos de Java que buscan una experiencia nativa en la nube tienen una variedad de opciones. Un marco Java nativo de la nube ideal aprovecha la profunda experiencia invertida en la plataforma Java y sus bibliotecas de terceros mientras las adapta para ejecutarse más rápido y con menos peso en la nube. Aquí hay ocho marcos Java creados desde cero para el desarrollo y la implementación nativos de la nube.

micronauta

Los creadores de Micronaut querían tomar las mejores partes de los marcos de Java clásicos como Spring y Grails, como la configuración flexible y la inyección de dependencia, pero eliminaron la gran cantidad de memoria y el inicio lento que los hacía menos deseables para desarrollar microservicios. Diseñaron cuidadosamente las anotaciones que brindan suficiente información para las inyecciones de dependencia sin la reflexión que llena la memoria que se usa en los marcos anteriores. Hacer más de la configuración de Micronaut en tiempo de compilación significa que el código se ejecuta más rápido y más liviano.

El marco está diseñado para admitir una variedad de lenguajes basados ​​en JVM (actualmente, Java, Kotlin y Groovy) y ejecutarlos en varias nubes. Los archivos de configuración predefinidos simplifican la implementación del servidor o las funciones sin servidor en todas las nubes principales, y hay páginas de documentación bien escritas para todas las conexiones de bases de datos principales.

Los desarrolladores de Micronaut también quieren que el marco respalde un buen trabajo en equipo de desarrollo. Se incluye una implementación de HttpClient con el proyecto para simplificar la escritura de pruebas unitarias sin salir de Micronaut ni agregar más trabajo. Estas pruebas suelen ser más sencillas y completas que las pruebas necesarias para los marcos dinámicos. Esto es, nuevamente, gracias al trabajo realizado en tiempo de compilación.

Micronaut no es solo para desarrollar aplicaciones con funciones en la nube. El marco es lo suficientemente general como para admitir roles tradicionales y algunas aplicaciones de escritorio. Su estrecha integración con GraalVM hace posible usar Micronaut para generar aplicaciones nativas.

Quarkus

Los desarrolladores que deseen utilizar una combinación bien entendida de código imperativo y reactivo pueden recurrir a Quarkus . El equipo de Quarkus comenzó anticipando los casos de uso más comunes para el desarrollo nativo de la nube, luego creó el marco con ejemplos que respaldan esos casos de uso con una configuración mínima. El resultado se transfiere fácilmente a un contenedor y se implementa en un clúster de Kubernetes .

El equipo de desarrollo prestó especial atención a garantizar tiempos de arranque rápidos para que los clústeres de Kubernetes puedan escalar rápidamente. Esta es una característica ideal para funciones que se ejecutan esporádicamente porque se pueden dejar frías hasta que se invoquen.

Uno de los objetivos del proyecto es adoptar y ampliar muchos estándares y bibliotecas existentes que son comunes en la comunidad Java. Por ejemplo, las anotaciones JAX-RS definen los puntos finales REST. La configuración comienza con Eclipse MicroProfile. El equipo de desarrollo de Quarkus también integró más de 50 bibliotecas estándar, por lo que es muy probable que reconozca los patrones de diseño en ciertos casos.

Puede utilizar el marco básico de Quarkus para una variedad de servicios. Comenzando con Quarkus 2.8, los desarrolladores de Quarkus están fomentando suavemente el modelo RESTeasy Reactive . Es la opción estándar si está comenzando un nuevo proyecto, pero no tiene que usarla. RESTeasy Reactive ofrece una estructura y patrones más simples y sin bloqueo. En lugar de asignar un subproceso a cada solicitud, un conjunto de subprocesos que no bloquean maneja todas las E/S e invoca su código cuando es necesario.

Quarkus también abarca una amplia gama de opciones de implementación. Si bien se dice que es “primero el contenedor”, puede ejecutarse sin sistema operativo. También hay una opción de configuración integrada llamada Funqy que simplifica la creación de las funciones aceptadas por AWS Lambda, Azure Functions, Knative y algunas otras opciones.

Funciones de la nube de primavera

Los desarrolladores de Java conocen bien Spring Framework porque ha sido la base de muchos proyectos durante aproximadamente dos décadas. Los desarrolladores de Spring deciden crear una nueva versión que se adapte mejor a la implementación en la nube, así como a otras funciones. Las funciones de Spring Cloud Functions están diseñadas para volver a implementarse fácilmente en una variedad de tareas, como servicios web, procesamiento de transmisiones o trabajo en segundo plano. 

El marco Spring Cloud Functions continúa muchas de las mismas tradiciones filosóficas iniciadas por Spring. Las funciones de la nube en este marco admiten un estilo reactivo o imperativo, así como una combinación híbrida de ambos.

Apoyar una amplia variedad de opciones es un gran objetivo para el proyecto. Hay adaptadores que calzan las funciones en AWS Lambda , Microsoft Azure , Apache OpenWhisk , Google Cloud Platform y algunos otros entornos comunes de funciones en la nube. También hay adaptadores para los principales marcos de transmisión como  Apache Kafka , Solace y RabbitMQ , así como la opción independiente Spring Cloud Stream . El empaquetado y la implementación están muy automatizados, por lo que puede concentrarse en desarrollar las funciones en sí.

El equipo de desarrollo de Spring Cloud Functions también trabajó arduamente para manejar muchos de los obstáculos y desafíos comunes de la implementación en la nube. Spring Cloud Skipper se puede utilizar para hacer malabarismos con las implementaciones en varias nubes. Spring Cloud Sleuth ayuda con la depuración al rastrear los flujos de datos. Spring Cloud Security administra muchas de las tareas para asegurar una aplicación para que solo las personas adecuadas puedan ejecutar las funciones. Solo hay varias docenas de subproyectos diferentes.

El proyecto es una muy buena base para distribuir aplicaciones comerciales a través de una variedad de plataformas. Una vez que la lógica de su aplicación se encapsula en un POJO de Cloud Function, puede encontrar un hogar trabajando en docenas de roles diferentes.

Vert.x

Los creadores de Vert.x querían crear un marco muy rápido simplificando el ciclo de eventos y optimizando la conexión con la base de datos. Vert.x tiene un solo bucle de eventos como Node.js, lo que le permite hacer malabarismos con varias conexiones a medida que llegan los eventos. También aprovecha el modelo de subprocesos de Java para procesar eventos con varios subprocesos en un grupo, que pueden ejecutarse en varios núcleos si están disponibles.

La estructura también está planificada para simplificar la creación de la canalización para procesar un flujo de eventos. Toma prestadas construcciones como promesas y futuros para evitar código desordenado con devoluciones de llamadas en capas. Las opciones asincrónicas ayudan a producir un código limpio y legible lleno de cadenas simples de invocaciones de métodos a medida que los eventos se mueven a lo largo del bus de eventos.

El equipo de desarrollo de Vert.x no es dogmático sobre su visión. A menudo dicen que Vert.x es un conjunto de herramientas, no un marco. El código es modular, por lo que puede elegir qué características usar y ensamblar una arquitectura que se adapte a su aplicación. Los programadores que quieren más una estructura imperativa en lugar de una reactiva pueden encontrar soporte para las corrutinas de Kotlin.

Este proyecto es parte del ecosistema Eclipse. Una variedad de versiones y opciones ofrecen mucha libertad. El generador de aplicaciones Vert.x , por ejemplo, producirá código Java o Kotlin con docenas de dependencias potenciales como motores de plantillas o compatibilidad con API.

Microperfil Eclipse

El equipo de Eclipse creó el proyecto MicroProfile como una forma de adaptar Jakarta EE para ejecutar constelaciones más pequeñas de microservicios. Elimina algunos de los gastos generales de la plataforma más grande mientras agrupa bibliotecas que son prácticamente estándar para muchas arquitecturas de microservicios.

El enfoque es más atractivo para los desarrolladores que podrían estar migrando código de proyectos Java EE o Jakarta EE más grandes y antiguos. Gran parte de la configuración y la arquitectura siguen siendo las mismas. En muchos casos, los ajustes son menores. Pero el diseño fomenta el tipo de decisiones que simplifican la creación de código más ligero y rápido. Algunos desarrolladores usan MicroProfile como un trampolín en el camino hacia marcos nativos de la nube más modernos.

Dropwizard

Algunos desarrolladores tienen un afecto natural por los módulos más antiguos y bien probados y disfrutarán de Dropwizard . El equipo de desarrollo de Dropwizard siempre ha enfatizado palabras como estable y maduro . Recopilaron módulos para conexiones de bases de datos como Hibernate y los combinaron en marcos para formularios y otros componentes estándar de aplicaciones web. Dropwizard también agiliza la inyección de dependencias y los procesos de mantenimiento en tiempo de ejecución, como la configuración y el registro.

Dropwizard es el favorito de los equipos que trabajan para revisar y ampliar una aplicación existente. La estructura es compatible con los enfoques más antiguos y maduros porque se basa en ellos.

Frameworks de inicio para plataformas en la nube

A veces, no hay necesidad de algo complejo o elaborado. Todas las nubes mantienen ejemplos básicos que son buenos lugares para comenzar a escribir funciones simples. Están diseñados principalmente para respaldar decisiones muy simples y ayudar a los desarrolladores a comenzar rápidamente.

Como ejemplo, el equipo de desarrollo de Google Cloud Platform abrió su marco básico para las funciones de Java que se ejecutan en su función como servicio (FaaS). El código creado con él está destinado a integrarse rápidamente con los activadores estándar de GCP, aunque también puede ejecutarse correctamente en cualquier máquina local.

Microsoft también abrió su marco para Java. El modelo incluye varias rutinas para simplificar las transferencias de datos, como una biblioteca para traducir datos JSON hacia y desde Java POJO. Si el disparador de la función proporciona metadatos con la invocación, el marco lo maneja directamente.

Ambos marcos le permiten realizar muchas tareas simples simplemente escribiendo una sola clase con una sola función. Es posible que los proyectos más complicados deseen fusionar esta herramienta básica con algunos de los otros marcos que he descrito. Estos son solo puntos de partida, pero a veces eso es suficiente.