Microservicios con Spring Boot (4/4)

Después de hacer una breve introducción a la plataforma Spring Boot, de ver cómo se crea un proyecto multimódulo con Gradle y de integrar microservicios con Spring Cloud, terminamos nuestro análisis a esta plataforma viendo cómo hacer uso de Docker Compose.

Esta herramienta, al tener múltiples servicios web, necesita una forma de automatizar el despliegue de todos estos servicios y poder realizarlo de la manera más rápida y sencilla posible. Docker Compose nos permite desplegar máquinas virtuales (containers) de Docker y a la vez gestionar la visibilidad entre ellas. Para poder desplegar un microservicio de Spring Boot el único requisito que debe tener la máquina en cuestión es que disponga de una versión de Java instalado, por lo que nos sirve cualquiera de las imágenes de Java ya creadas.

compose

Crearemos un fichero docker-compose.yml para definir el entorno compuesto por MongoDB, RabbitMQ y Eureka. Se creará en un servicio aparte para poder reutilizar en otros proyectos. Por otro lado tendremos un entorno con todas las máquinas simulando un entorno de producción, y otro en el que ejecutaremos los test para que la ejecución de los mismos sea lo más similar posible al entorno real.

Estructura de los ficheros docker-compose.yml:

1

En el primer nivel se define el hostname de la máquina y en un segundo nivel las propiedades que va a tener dicho host. Estos son los atributos que necesitamos:

  • Debe tener un atributo build o image que especifique la imagen que se va a desplegar en el container. En el caso de build se define la ruta a un fichero Dockerfile mientras que en el caso de image se especifica una imagen que esté en el equipo o por el contrario haya sido comiteada en hub.docker.com.
  • El atributo container_name indica el nombre que va a recibir el container. Si se pone un nombre fijo puede haber colisiones cuando se inicien varias instancias de la misma máquina. No es un atributo necesario y, si no se indica, genera un nombre incremental de forma automática.
  • El atributo volumes nos permite mapear directorios locales en la estructura de ficheros del container. Para que exista conectividad con ese container se debe especificar los puertos que se mapean con el host anfitrión. Son dos puertos separados por dos puntos que indica que puerto del anfitrión se mapea al puerto del container. Si se omite el primer puerto se mapea a un puerto aleatorio del host anfitrión.
  • El atributo expose permite que la máquina sea accedida por otras máquinas definidas en otro docker-compose.yml
  • El atributo link añade a la máquina a crear un enlace añadiendo el mapeo en el archivo de host para que sea capaz de resolver el nombreHost definido en el primer nivel.
  • El atributo external_link es similar al anterior pero con equipos definidos en otro docker-compose.yml
  • El atributo environment añade las variables de entorno que se indiquen.
  • Por último, command nos permite indicar el comando que se va a ejecutar al inicio.

Los mínimos requeridos para definir un container son imagen (o build) y port.

Entorno

Para definir el entorno hemos aprovechado que ya existía una imagen en Docker Hub de Eureka y hemos eliminado dicho proyecto de nuestro código. Para iniciar el entorno tan solo hay que entrar en el directorio docker/env y ejecutar el comando docker-compose up -d. Esto crea los containers Eureka, MongoDB y Rabbitmq. El equipo con Mongo ya tiene los datos de ejemplo.

Podemos acceder a cualquiera de ellos usando la IP de Docker y el puerto adecuado. (En Windows se puede obtener con docker.machine ls).

Para parar el entorno tan solo tenemos que ejecutar docker-compose stop en el mismo directorio.

Test

Para ejecutar los test hemos creado un Docker que incluye con el atributo volumes la ruta del proyecto en el directorio/app e indicamos que existe un enlace externo con los equipos del entorno indicado anteriormente, esto nos define una ruta en el host test para que pueda acceder a Eureka, MongoDB y Rabbitmq.

Se han modificado los servicios para incluir un profile de configuración específico para Docker usando los nombres de Host Eureka, MongoDB y Rabbitmq, la forma de usar esta configuración es definiendo dentro del atributo environment la variable de entorno SPRING_PROFILES_ACTIVE con valor Docker.

El container se iniciará ejecutando los test y dejando el resultado de esta ejecución en build\reports.

La forma de iniciar este entorno es similar a la anterior, debe estar iniciado el entorno y en docker/test ejecutar docker-compose up -d.

Servicios de Spring Boot

Para las imágenes de Spring Boot se ha indicado que la imagen base es una imagen de openjdk y el profile de Spring Boot a usar en este caso el profile es Docker.

Para ejecutar el entorno tenemos que haber generado los distintos artefactos con un Gradle build en la raíz del proyecto luego en el directorio docker/deploy se lanza el entorno con el comando docker-compose up -d y esto nos inicia las tres máquinas de user, product y agregation.

Ahora al acceder con la IP de Docker a la URL del servicio de agregation este nos responde con el resultado esperado.

2

Conclusión

En esta serie de artículos hemos visto cómo crear microservicios de forma sencilla para que el hecho de tener múltiples microservicios no suponga un coste de desarrollo excesivo. Además, nos hemos ayudado de las ventajas que nos aporta Spring Cloud, que nos resuelve el problema de la coordinación de los mismos implementando por nosotros muchos de los patrones más útiles en este campo. Y para gestionar el despliegue de los distintos microservicios nos apoyamos en Docker, que nos simplifica el proceso permitiéndonos desplegarlos todos a la vez con un solo comando.

Con todo esto, los microservicios nos permiten afrontar un problema complejo dividiéndolo en partes más sencillas una estrategia muy potente que, implementada correctamente, nos permite un escalado horizontal que maximiza las posibilidades del éxito de nuestros proyectos.

 

Analizamos a fondo Microservicios con Spring Boot en 4 entregas:

Su rol es el de arquitecto software, especializado en tecnologías J2EE. Se trata de seleccionar tecnologías para desarrollos de proyectos desde cero, implementando patrones de software y buenas prácticas de desarrollo . Esto facilita la codificación de las reglas de negocio de forma que los programadores no tengan que preocuparse por la arquitectura que subyace y que ésta les facilite la programación.

Ver toda la actividad de Javier Ledo

Recibe más artículos como este

Recibirás un email por cada nuevo artículo.. Acepto los términos legales

Escribe un comentario