Vert.x, el nacimiento de un Súper Saiyan (2/2)

En la primera entrega de Vert.x vimos cosas imprescindibles para poder entender esta segunda parte. Haciendo un poco de memoria hablamos sobre el funcionamiento interno de Vert.x y los componentes que lo forman, términos como even loop, worker o nuestro event bus deberían estar muy claros.

En el caso de la tematización sucede lo mismo, Goku seguirá evolucionando a medida que avanzamos en complejidad en nuestra librería. ¡Empecemos esta segunda parte!

Copyright: Akira Toriyama

El poder del cluster

Ahora, antes de empezar con la parte de los microservicios propiamente dicha, hablamos sobre el cluster de Vert.x. ¿Qué es? ¿Cómo funciona? ¿Para qué sirve?

El cluster de Vert.x nos permitirá unir tantas instancias de Vert.x como queramos cuyo comportamiento resultante será como si de una sóla se tratase.

Algo muy interesante a analizar con respecto al cluster, y como introductorio de los microservicios, es el verdadero significado del término políglota. Está claro que Vert.x permite varios lenguajes de programación, pero lo interesante es la transparencia que el bus proporciona sobre los detalles de la implementación.

Por ejemplo, podríamos tener un “verticle” encargado del acceso a MongoDB en NodeJS y nosotros simplemente deberíamos conocer su nombre para comunicarnos desde el lenguaje que sea a través del bus.

El objetivo del cluster será ofrecer lo siguiente: alto rendimiento, alta disponibilidad, balanceo de carga y escalabilidad algo imprescindible a día de hoy en cualquier arquitectura contemporánea.

Ejemplo de cluster de Vert.x

Tanto el cluster de Vert.x como casi todas las partes referentes a las arquitecturas de microservicios con Vert.x son “pluggables” basadas en Java Service Loader.

La implementación por defecto usa Hazelcast, pero ofrece otras mediantes otros sistemas: Zookeeper, Infinispan, Apache Ignite o bien si lo deseas hacer la tuya propia a través de unos sencillos pasos.

Existirá la figura del cluster manager que será el encargado de orquestar todo lo necesario para el correcto funcionamiento:

  • Descubrirá nuevos miembros y generará los eventos necesarios para que el resto sean informados de la existencia de dichos miembros.
  • Almacenará toda la metainformación de los componentes del cluster (IP,s, direcciones, nombres de los servicios…).
  • Manejará toda la información distribuida en los nodos: map distribuidos, contadores distribuidos…
  • Controlará los bloqueos distribuidos del acceso a información compartida entre nodos.
  • Guardará la información referente a la alta disponibilidad si el sistema ha sido configurado en alta disponibilidad.

Nivel superior: Microservicios

Nos encontramos en la etapa final de nuestro curso en cuanto a teoría: ¡los microservicios! Vert.x define a los microservicios como:

“Microservices are small, autonomous services that work together”.

Copyright: Akira Toriyama

No vamos a entrar a definir el término Microservicios, ya que está muy extendido y nos vamos a centrar en qué ofrece Vert.x para su implementación y los elementos que los componen.

Service Discovery

Este componente provee de una infraestructura para publicar y descubrir los recursos disponibles (para el Service Discovery recurso = servicio ), los cuales pueden ser de varios tipos: proxies, HTTP endpoints, data sources…​

Los componentes del Service Discovery serán:

  • Service record: toda la información de cada uno de los recursos será almacenada en lo que Vert.x denomina Record, será la descripción completa del servicio en cuanto a metainformación se refiere.
  • Service providers: serán los encargados de publicar, despublicar y modificar el estado (UP, DOWN, OUT_OF_SERVICE) de los servicios.
  • Service consumers: encargados de recuperar el servicio y de obtenerlo de modo correcto según su tipo (ServiceReference o de modo directo si conoce el tipo).
  • Service object: objeto de acceso al servicio, será diferente dependiendo de la naturaleza del servicio.
  • Service Events: todos los eventos se producen sobre el bus, publicación, baja, modificación, referencias… los cuales son registrados a modo de estadística en una dirección del bus.

Los tipos de servicios que podemos publicar serán:

  • HTTP endpoints: REST API o un servicio accesible por HTTP.
  • Event bus services: son los services proxy, implementados con async-RPC.
  • Message source: consumimos mensajes dentro del bus, publicación-suscripción en una dirección.
  • JDBC, Mongo, Redis: tipos de acceso a persistencias.
  • Servicios custom: nos permite crear tipos de servicios implementando la interfaz  ServiceType SPI.

Circuit Breaker

Es el componente de la arquitectura que controla la latencia y la tolerancia a fallos.

Sus principales funciones serán:

  • Protección del sistema: aumenta su resistencia mediante la detención de los fallos en cascada.
  • Supervisión de los fallos y toma de decisiones (mediante eventos).
  • Control de los umbrales de error y respuesta (“open circuit”).
  • En algunos casos generación de estadísticas, alertas y monitores. La implementación de Vert.x notifica al una dirección del bus toda esta información la cual puede unirse al Netflix Hystrix Dashboard.
  • Provee de eventos de acción en las situaciones de “open circuit” y “close circuit”.

Vert.x Config

Para la implementación de microservicios necesitaremos una gestión de la configuración la cual Vert.x nos ofrece con Vert.x Config.

Sus características generales son:

  • Soporta diferentes formatos de ficheros: json, properties, yaml, hocon…​ pero de cara a la programación las recibiremos y consumiremos como un Json.
  • Posee diferentes implementaciones de “stores”: files, directorios, HTTP, Git , Redis, system properties, environment properties, Spring Config, Kubernetes, Zookeeper…
  • Si existen varios stores, se puede establecer el orden de lectura y las prioridades, convención de lectura y sobreescritura de propiedades.
  • Posee la posibilidad de actualización de valores en tiempo de ejecución y eventos asociados.

Todo lo visto hasta ahora a grandes rasgos lo podremos ver en la tercera parte del curso más en detalle con ejemplos de código.

Saiyan Challenge

Estamos en la etapa final del aprendizaje sobre Vert.x y qué mejor manera de descubrir “el poder que encierra” que con un juego.

Os explicaremos a grandes rasgos en qué consiste para no desvelar alguno de los detalles de la puesta en escena.

Copyright: Akira Toriyama

Hemos creado un juego cuya finalidad es demostrar la potencia de nuestro Vert.x como si de un guerrero se tratase mediante una “pseudo” arquitectura de microservicios. La denominamos así ya que no existirá crecimiento horizontal por la infraestructura en la cual se ha montado.

El juego está inspirado en la arquitectura de ejemplo disponible en Blue Print de Vert.x, el cual os puede servir de base para las ideas que se os ocurran, así lo hice yo ;)

Los microservicios del juego serán:

Los usuarios se conectarán y se les asociará un enemigo automáticamente mediante el cual podrán simular ataques (por cada clic ,100 peticiones) sobre nuestro guerrero Goku.

Goku poseerá una “barra de vida”, que será la media resultante del consumo de  CPU de los microservicios desplegados llamados Saiyan, es decir, cuanto más CPU consumida menos vida y es ahí donde nuestro guerrero intentará subir de nivel (como sucede en la serie) para intentar hacer frente a todos los enemigos.

El microservicio Enemy poseerá un recurso que será el encargado de asignar el enemigo, en este caso, de forma aleatoria.

El microservicio Challenge-UI será la interfaz visual, la cual está hecha con HTML5 y JQuery. A destacar el uso de Websockets para refrescar la “barra de vida” de Goku mediante SockJS más la librería Javascript de Vert.x para el acceso al bus.

Por último, el Api-Gateway, que está hecho en Vert.x completamente, pertenece al ejemplo de Blue Print nombrado antes. Se encargará de hacer de proxy inverso, descubriendo e invocando a los servicios, realizará labores de balanceo muy básicas y comprobará el estado de los microservicios apoyándose en el circuit breaker.

Os invitamos a que viváis vuestra propia experiencia con el juego mediante el vídeo:

Conclusión

Como hemos visto, Vert.x puede ser un poderoso aliado sobre todo en arquitecturas que necesiten de un rendimiento muy alto o en aplicaciones que necesiten usar muy pocos recursos. A día de hoy nos ofrece un conjunto de componentes para hacer aplicaciones reactivas de microservicios: Service Discovery, Circuit Breaker, Config…

Ha incluido el concepto de “pluggable” en algunas de sus partes permitiéndonos elegir las integraciones con otros subsistemas que queramos, por ejemplo en el Cluster Manager, Vert.x Config…

En contra, diría que la programación asíncrona posee una curva de aprendizaje mayor que la síncrona o más tradicional. En Vert.x todo es asíncrono, pero creo que eso no debería ser un impedimento, yo lo transformaría en meta y empezaría a disfrutar de este compañero tecnológico.

Arquitecto de profesión, pero con corazón de programador ;) Mi objetivo del día a día es aprender, disfrutar de lo que hago y enriquecerme con las personas que me rodean. Con más de 15 años en el mundo del desarrollo e intentando seguirle el ritmo a las nuevas tecnologías.

Ver toda la actividad de J. Manuel García Rozas