Sunteți pe pagina 1din 58

UNIVERSIDAD MAYOR DE SAN SIMON

FACULTAD DE CIENCIAS Y TECNOLOGIA


DIRECCIÓN DE POSGRADO

“ARQUITECTURA BASADOS EN MICROSERVICIOS:


SPRING CLOUD Y NETFLIX OSS PARA APLICACIONES
CONTERIZADOS”

TRABAJO FINAL PRESENTADO PARA OBTENER EL CERTIFICADO DE DIPLOMADO


EXPERTO EN DESARROLLO DE APLICACIONES EMPRESARIALES

POSTULANTE: Ing. RICARDO EDMUNDO VEIZAGA LOZADA.


TUTOR: Msg. VALENTIN LAIME ZAPATA.

Cochabamba – Bolivia
2019
Quiero agradecer en primer lugar a DIOS por
darme la fortaleza y perseverancia para llegar a
este punto, a mi madre que estuvo a mi lado cada
día del presente diplomado, a mi padre que estuvo
apoyándome con las decisiones a tomar y el apoyo
incondicional de mis hermanitos.
Tabla de contenidos
Resumen ..................................................................................................................................... 8
1. Introducción.......................................................................................................................... 9
1.1. Generalidades ................................................................................................................ 10
1.1.1. Antecedentes Generales ............................................................................................ 10
1.1.2. Antecedentes Específicos .......................................................................................... 11
2. Metodología ....................................................................................................................... 11
2.1. Definición del problema.................................................................................................. 11
2.2. Búsqueda de la información .......................................................................................... 11
2.3. Análisis de la información .............................................................................................. 11
3. Definiendo la arquitectura de microservicios .................................................................... 12
3.1. Arquitectura orientada a servicios ................................................................................. 12
3.2. Arquitectura de microservicios ....................................................................................... 13
3.3. Arquitectura monolítica y microservicios ....................................................................... 14
3.4. Beneficios y desventajas de microservicios .................................................................. 15
3.5. Spring cloud y Netflix OSS ............................................................................................. 15
4. Comunicación de microservicios ....................................................................................... 16
4.1. Tipos de comunicación .................................................................................................. 17
4.2. Estilos de comunicación................................................................................................. 19
4.2.1. Comunicación con HTTP y REST .............................................................................. 20
4.2.2. Comunicación en tiempo real ..................................................................................... 20
4.2.3. Comunicación basada en mensajes asíncronos ....................................................... 21
4.2.3.1. Comunicaciones de receptor único ........................................................................ 22
4.2.3.2. Comunicación de receptores múltiples .................................................................. 23
5. Proceso de desarrollo ........................................................................................................ 24
5.1. Flujo de trabajo............................................................................................................... 24
5.2. Microservicios con Spring Boot...................................................................................... 25
5.2.1. Spring Boot Starters ................................................................................................... 25
5.2.2. Spring Boot Autoconfiguración ................................................................................... 26
5.2.3. Gestión de la configuración elegante ......................................................................... 26
5.2.4. Soporte de contenedor de servlets integrado fácil de usar ....................................... 26
5.2.5. Creando una aplicación Spring Boot ......................................................................... 26
5.2.6. Spring Boot desde IDE ............................................................................................... 27
5.3. Spring Cloud: Diseñando la arquitectura de microservicio ........................................... 28
5.3.1. Spring Cloud servidor de configuración ..................................................................... 28
5.3.1.1. Construir servidor de configuración ........................................................................ 29
5.3.1.2. Configurar el servidor de configuraciones .............................................................. 30
5.3.1.3. Configurar la clase Bootstrap ................................................................................. 31
5.3.2. Spring Cloud servicio Discovery ................................................................................ 32
5.3.2.1. Construir el servicio de Spring Eureka ................................................................... 32
5.3.2.2. Configurar el servicio Eureka ................................................................................. 33
5.3.2.3. Configurar la clase Bootstrap ................................................................................. 34
5.3.3. Servicio de enrutamiento con Spring Cloud y Zuul ................................................... 34
5.3.3.1. Construir el servicio de Spring Gateway ................................................................ 35
5.3.3.2. Configurar el servicio Gateway ............................................................................... 36
5.3.4. Bus de eventos ........................................................................................................... 38
5.3.4.1. El intermediario: RabbitMQ..................................................................................... 38
5.3.4.2. RabbitMQ y conceptos de servidor ........................................................................ 39
5.4. Infraestructura de persistencia....................................................................................... 40
5.4.1. Construir el microservicio de la persistencia ............................................................. 41
5.5. Contenerizando microservicios ...................................................................................... 43
5.5.1. Terminología Docker .................................................................................................. 44
55.2. Construyendo aplicaciones desde un contenedor .......................................................... 46
5.6. Infraestructura de Servicios ........................................................................................... 48
5.6.1. FeignClient con Spring Cloud..................................................................................... 48
5.6.2. Implementando el patrón Command .......................................................................... 50
5.6.3. Construir el microservicio ........................................................................................... 51
5.7. Infraestructura de la Interfaz de usuario ........................................................................ 54
6. Conclusiones...................................................................................................................... 57
Bibliografía................................................................................................................................. 58
Contenido de figuras
Figura 1. Despliegue monolítico versus el enfoque de microservicios ........................................... 14
Figura 2: Comparación de la soberanía de datos: base de datos monolítica versus
microservicios ......................................................................................................................................... 17
Figura 3: Patrones y anti-patrones en la comunicación entre microservicios ................................ 19
Figura 4: Usando comunicación por petición/respuesta HTTP (síncrona o asíncrona) ............... 20
Figura 5: Comunicación asíncrona por mensaje en tiempo real uno-a-muchos ........................... 21
Figura 6: Un microservicio recibiendo un mensaje asíncrono ......................................................... 22
Figura 7: Comunicación asíncrona por mensaje basada en eventos ............................................. 23
Figura 8: Flujo de trabajo, paso-a-paso para desarrollar aplicaciones Docker contenerizadas.. 25
Figura 9: Spring Initializer. .................................................................................................................... 27
Figura 10: IDEA JetBrains creando una aplicación Spring Boot. .................................................... 28
Figura 11: Los datos de configuración de la aplicación se leen durante la fase de arranque del
servicio. ................................................................................................................................................... 29
Figura 12: Configuración del pom.xml para el servidor de configuración de Spring Cloud ......... 30
Figura 13: El archivo application.properties de la configuración de Spring Cloud ........................ 31
Figura 14: La clase de arranque para el servidor Spring Cloud Config .......................................... 31
Figura 15: El equilibrio de carga del lado del cliente almacena en caché la ubicación de los
servicios................................................................................................................................................... 32
Figura 16: Configuración del pom.xml para el servicio de Eureka de Spring Cloud ..................... 33
Figura 17: El archivo application.properties del servicio Eureka de Spring Cloud ........................ 34
Figura 18: La clase de arranque para el servicio Spring Cloud Eureka ......................................... 34
Figura 19: Arquitectura del servicio Gateway usando los servicios de registros y configuraciones
.................................................................................................................................................................. 35
Figura 20: La clase de arranque para el servicio Spring Cloud Gateway ...................................... 36
Figura 21: Configuración del pom.xml para el servicio Gateway de Spring Cloud ....................... 37
Figura 22: El archivo application.properties del servicio Gateway de Spring Cloud ..................... 38
Figura 23. Aspectos básicos de publicación/suscripción con un bus de eventos ......................... 38
Figura 24: Infraestructura de comunicación del Servicio y la Persistencia. ................................... 40
Figura 25: Servicio de registro o Eureka de la persistencia. ............................................................ 41
Figura 26: Configuración del pom.xml para la persistencia de Explanations ................................ 41
Figura 27: Archivo de configuración para la persistencia de Explanations .................................... 42
Figura 28: Comunicación con el Config para la persistencia de Explanations .............................. 42
Figura 29: La clase de arranque para la persistencia de Explanations .......................................... 43
Figura 30: Contenedores desplegados en un entorno...................................................................... 43
Figura 31: Compilando la aplicación en un contenedor de construcción. ...................................... 46
Figura 32: Ejecución del comando Maven. ........................................................................................ 46
Figura 33: Ejecución del comando de construcción del Docker ...................................................... 47
Figura 34: Comando del ejecutador del contenedor. ........................................................................ 47
Figura 35: Visualizador de contenedores ejecutados. ...................................................................... 48
Figura 36: Dependencia administrativa de Spring Cloud. ................................................................ 49
Figura 37: Dependencia de FeignClient de Spring Cloud. ............................................................... 49
Figura 38: Configuración del FeignClient. .......................................................................................... 49
Figura 39: Configuración del Cliente Feign. ....................................................................................... 50
Figura 40: Configuración POM del servicio Explanations ................................................................ 52
Figura 41: Configuración YML del servicio Explanations. ................................................................ 53
Figura 42: La clase de arranque para el servicio de Explanations.................................................. 53
Figura 43: Servicio de Registro o Eureka de los servicios. .............................................................. 54
Figura 44: Interfaz de usuario monolítica consumiendo microservicios de backend.................... 54
Figura 45: Configuración del ambiente de la comunicación con Backend. .................................... 55
Figura 46: Comandos de ejecución de la Interfaz de usuario.......................................................... 56
Figura 47: Visualización de la interfaz de usuario de Explanations. ............................................... 56
Contenido de tablas
Tabla 1: Comparación entre Aplicaciones monolíticas y basada en microservicios..................... 13
Tabla 2: Ventajas y desventajas del uso de microservicio ............................................................... 15
Tabla 3: Componentes operacionales................................................................................................. 16
Tabla 4: Conceptos Básicos de RabbitMQ ......................................................................................... 40
Tabla 5: Terminologías con Docker..................................................................................................... 45
Tabla 6: Construcción del patrón Command ...................................................................................... 51
Resumen

Hoy en día es habitual mencionar sobre los proyectos que usan o se basan en arquitecturas de
desarrollo de diferentes manera, uno de los casos más usuales son los microservicios.

Tener habilidades o el conocimientos del por qué o cómo hacerlo con estas arquitecturas es de
suma importancia para todo desarrollador de software, para el cual plantear una arquitectura a
tu aplicación se debe conocer las distintas herramientas que nos brinda el mundo de los
microservicios.

Este trabajo nos muestra una visión general del conocimiento que debemos estar al corriente
sobre las comunicaciones ente diferentes sistemas que utilizan arquitecturas similares y el
proceso iterativo con los servidores que proveen el enlace entre los sistemas.

Se realizara el análisis de los tipos más comunes de arquitecturas basados en microservicios y


el afecto de utilizarla a la hora de realizar una aplicación de software.

Se eligió las tecnologías de Spring Cloud para la capa de servicios y Netflix OSS para la capa
de persistencia, teniendo dos arquitecturas funcionales para nuestra aplicación de software,
cabe mencionar también el ciclo de vida del desarrollo de microservicios, el cual se llevara a
cabo los procesos y practicas necesarias de DevOps desde una perspectiva para los
microservicios.
1. Introducción

Cada vez más, las empresas están logrando ahorros en los costes, resolviendo problemas de
despliegue de las aplicaciones y mejorando las actividades de desarrollo y operaciones, con la
utilización de servicios en contenedores. Muchas empresas han desarrollado y liberado
innovaciones con el uso de contenedores para Windows y para Linux, creando grandes
productos que se manejan en la nube, sin importar las plataformas o herramientas que utilicen.

Docker se ha convertido en el estándar de facto en la industria de contenedores, siendo


soportado por las empresas más significativas en los ecosistemas de Windows y Linux. En un
futuro, Docker será omnipresente en cualquier centro de datos en la nube o en instalaciones
internas.

Además, la arquitectura de microservicios está surgiendo como un enfoque importante para las
aplicaciones distribuidas de misión-critica. En una arquitectura basada en microservicios, la
aplicación se construye como una colección de servicios que se puede desarrollar, probar,
desplegar y versionar de forma independiente.

En la actualidad es indispensable que las aplicaciones estén diseñadas para que se


comuniquen con los entornos móviles, web y de escritorio e incluso nuestras aplicaciones
alcancen a desplegar y consumir información; como ejemplo podemos citar la autenticación
mediante las redes sociales.

Al usar microservicios, cada cambio solo necesita empaquetar el servicio afectado, el


programador nuevo incluido en el equipo fácilmente se adapta a todos esos nuevos cambios
aplicados al servicio; por naturaleza los microservicios tienden a tener una sola responsabilidad
y el programador solo tiene que ver esa lógica de negocio y rápidamente puede empezar a
programar.

Existen mecanismos extra que es necesario considerar como el Service Discovery, API
Gateway que son temas que se verán más adelante.

Algo tan sencillo como la comunicación entre módulos en el sistema monolítico que solo
consiste en llamar a métodos y funciones de las clases. En microservicios la comunicación se
vuelve un poco más complicada, y requiere de otros elementos que se representarán en la
Comunicación entre Microservicios.
1.1. Generalidades

1.1.1. Antecedentes Generales

Los Microservicios es una forma de diseñar aplicaciones de tal forma que puedan ser utilizadas
y desplegadas de forma independiente. Generalmente implementan una funcionalidad atómica
del negocio, facilitan el despliegue automatizado, cuentan con inteligencia de endpoints y tiene
un control descentralizado de lenguajes de programación y motores de base de datos.

Una arquitectura orientada a microservicios, consiste en un sistema distribuido que alberga


pequeñas aplicaciones independientes, que se ejecutan y despliegan de forma individual,
según las necesidades y que, a su vez, se comunican con la parte cliente o incluso entre ellas a
través de sus API.

Este tipo de arquitecturas surge como dilema y trae una serie de ventajas respecto a las
arquitecturas monolíticas. La principal es la posibilidad de crear sistemas basados en
aplicaciones independientes de pocos recursos, que se despliegan de forma autónoma, que a
su vez se pueden combinar, reutilizar o eliminar, sin que esa modificación afecte al resto de los
componentes o servicios y sin que se produzca ninguna interrupción. Además la configuración
individual nos permite tal flexibilidad, que incluso pueden estar escritos con diferentes lenguajes
de programación.

No obstante, la contenerización es un enfoque de desarrollo de software en el que una


aplicación o servicio, sus dependencias y su configuración se empaquetan juntos como una
imagen de contenedor (o simplemente imagen para simplificar, cuando no haya ambigüedad).
Una aplicación basada en contenedores se puede probar como una unidad y desplegar como
una instancia de la imagen, en el sistema operativo que funciona como host.

Los contenedores también aíslan las aplicaciones de otras instaladas en un sistema operativo
(SO) compartido. Las aplicaciones contenerizadas se ejecutan en un host de contenedores
que, a su vez, se ejecuta sobre el sistema operativo (Linux o Windows). Por eso, los
contenedores son significativamente más livianos que las imágenes de máquinas virtuales
(VM).

En resumen, los contenedores ofrecen los beneficios de aislamiento, portabilidad, agilidad,


escalabilidad y control, a lo largo de todo el ciclo de vida de las aplicaciones.
1.1.2. Antecedentes Específicos

Utilizar y aprovechar las características principales del framework Spring Cloud y Netflix
OSS, para establecer mecanismos de comunicación entre diferentes tipos de
aplicaciones utilizando REST (Transferencia de Estado Representacional).

2. Metodología

La metodología propuesta para la revisión bibliográfica puede ser aplicada a cualquier tema de
investigación para determinar la relevancia e importancia del mismo y asegurar la originalidad
de una investigación. Además, permitir que otros investigadores consulten las funestes
bibliográficas citadas, pudiendo entender y quizás continuar el trabajo realizado. La
metodología propuesta se compone de tres fases:

2.1. Definición del problema

Debe ser lo suficientemente clara para poder realizar una búsqueda bibliográfica que responda
a las necesidades del investigador en particular, y que además aporte al estado de la técnica,
de manera que conduzca a un escenario bastante amplio y permita la retroalimentación de la
investigación.

2.2. Búsqueda de la información

Para el proceso de investigación bibliográfica se debe contar con material informativo como
libros, revistas de divulgación o de investigación científica, sitios Web y demás información
necesaria para iniciar la búsqueda.

2.3. Análisis de la información

La tercera fase es analizar la información ya organizada, indagando sobre cuáles son los
documentos más útiles para la temática en estudio. El análisis de la información es la tarea que
toma más tiempo en la investigación bibliográfica, ya que con ella se espera identificar el aporte
a realizar. En esta fase se debe tener un pensamiento crítico y debe ser realizada en paralelo
con la primera, dado que es un proceso constante. Es un ciclo donde se reafirman las ideas
planteadas en la formulación del problema y si se conoce bien el problema, la solución estará al
alcance.

3. Definiendo la arquitectura de microservicios

Los microservicios ofrecen grandes beneficios, pero también plantean enormes desafíos, Los
patrones de arquitectura de microservicios son los pilares fundamentales para crear
aplicaciones basadas en microservicios.

Las aplicaciones empresariales pueden ser complejas y a menudo se componen de múltiples


servicios en lugar de una sola aplicación basada en servicios. Para esos casos, aun cuando los
contenedores son habilitadores y se adaptan perfectamente a los microservicios, no son
obligatorios este tipo de arquitectura y muchos de los conceptos que veremos más adelante,
también podrían aplicarse sin contenedores, pero dicha intersección de ambos es debida
importancia el uso de los contenedores.

3.1. Arquitectura orientada a servicios

La arquitectura orientada a servicios (SOA) fue un término usado en exceso y ha significado


diferentes cosas para distintas personas. Pero como denominador común, SOA significa que
una aplicación se estructura descomponiéndola en múltiples servicios (más comúnmente como
servicios HTTP) que pueden clasificarse en diferentes tipos, como subsistemas o capas.

Esos servicios ahora se pueden implementar como contenedores Docker, lo que resuelve
problemas de despliegue, porque todas las dependencias están incluidas en la imagen del
contenedor. Sin embargo, cuando necesite escalar aplicaciones SOA, puede tener problemas
de escalabilidad y disponibilidad si está desplegando en base a hosts Docker únicos. Aquí es
donde el software de gestión de cluster Docker o un orquestador le ayudarán, tal como se
explica en secciones posteriores donde describimos enfoques de despliegue para
microservicios.

Los microservicios se derivan de SOA, pero SOA es diferente de la arquitectura de


microservicios. Las características como grandes agentes centrales (central brokers),
orquestadores centrales a nivel de organización y el Enterprise Service Bus (ESB) son típicos
en SOA. Pero en la mayoría de los casos, estos son anti patrones en la comunidad de
microservicios. De hecho, algunas personas argumentan que "la arquitectura de microservicio
es SOA implementada correctamente".

3.2. Arquitectura de microservicios

Una arquitectura de microservicios es un enfoque para construir una aplicación de servidor


como un conjunto de pequeños servicios. Es decir, una arquitectura de microservicios está
orientada fundamentalmente hacia el back-end, aunque también se está usando el enfoque
para el front-end. Cada servicio se ejecuta en su propio proceso y se comunica con otros
procesos utilizando protocolos como HTTP/HTTPS, WebSockets o AMQP. Cada microservicio
implementa una funcionalidad específica, de principio o fin, del negocio o del dominio, dentro
de los límites de cierto contexto. Además, cada uno se debe poder desarrollar y desplegar de
forma independiente. Finalmente, cada microservicio debe poseer su modelo de datos y su
lógica de dominio relacionados (soberanía y gestión descentralizada de datos) que pueden
estar basados en diferentes tecnologías de almacenamiento de datos (SQL, NoSQL) y
diferentes lenguajes de programación.

¿Por qué una arquitectura de microservicios? En resumen, porque proporciona agilidad a largo
plazo. Los microservicios facilitan el mantenimiento en sistemas complejos, grandes y que
requieren alta escalabilidad, porque permiten crear aplicaciones basadas en muchos servicios,
que se despliegan independientemente y que tienen ciclos de vida granulares y autónomos.

Aplicación monolítica contenerizada Aplicación basada en microservicios

Una aplicación tradicional tiene la mayoría de Una aplicación basada en microservicios


su funcionalidad en unos pocos procesos divide la funcionalidad servicios
componentizados en capas y librerías independientes más pequeños

Se escala clonando la aplicación en múltiples Se escala desplegando cada servicio


servicios o máquinas virtuales independientemente, en múltiples instancias
en varios servidores o máquinas virtuales

Tabla 1: Comparación entre Aplicaciones monolíticas y basada en microservicios


Figura 1. Despliegue monolítico versus el enfoque de microservicios

Como beneficio adicional, los microservicios se pueden escalar de forma independiente. En


lugar de tener una aplicación única monolítica, que se debe escalar como una unidad, se
pueden escalar individualmente microservicios específicos. De esta forma, puede escalar sólo
el área funcional que necesita más potencia de procesamiento o ancho de banda de red para
soportar la demanda, en lugar de ampliar otras áreas de la aplicación que no necesitan
escalarse. Eso significa ahorros de costes porque se aprovechan mejor los recursos y se
necesita menos hardware.

3.3. Arquitectura monolítica y microservicios

Una arquitectura basada en microservicios granulares, es un facilitador para las prácticas de


integración y entrega continuas (CI/CD). También ayuda a entregar más rápido las nuevas
funciones en la aplicación, ya que la composición fina de las funciones le permite ejecutar y
probar microservicios en forma aislada y desarrollarlos de manera autónoma, manteniendo
claros los contratos entre ellos. Siempre que no cambie las interfaces o los contratos, puede
cambiar la implementación interna de cualquier microservicio o agregar nuevas funcionalidades
sin romper otros microservicios.

Entre las principales diferencias entre las arquitecturas monolíticas y los microservicios es que,
Una de las principales características de esta arquitectura es que, cada microservicio puede
tener su propia base de datos y el acceso es a través de la interfaz de usuario.
3.4. Beneficios y desventajas de microservicios

Ahora ya sabemos que son los microservicios así como su arquitectura y características
principales. Por ello, vamos a detallar algunas de sus ventajas y desventajas.

Ventajas Desventajas

Divide los componentes de una aplicación en Mayor complejidad, el desarrollo puede ser
varios servicios independientemente, teniendo riesgoso cuando la funcionalidad es muy
diferentes servicios como parte de la compleja para ser fragmentada en servicios
aplicación.

Los componentes de servicio se pueden Mayor gestión, se debe asegurar que todos
implementar en diferentes máquinas virtuales los desarrolladores conozcan cada uno de los
en función a su carga de trabajo. servicios, esto implica un alto nivel de
comunicación del equipo.

Más expectativas para los servicios Mayor complicación en relación a


subyacentes, con respecto al lenguaje de infraestructura, el uso de memoria puede ser
programación, dado que cada servicio es una alta y requerir el uso de Gateway o
entidad separada, cada servicio pueden estar contenedores.
escrito en un lenguaje diferente.

Los servicios pueden ser fácilmente Pruebas más confusas, al estar la


reemplazados o actualizados, entrega funcionalidad fragmentada puede llevar a que
continua. las pruebas no sean tan claras o simples
como en una aplicación monolítica
Tabla 2: Ventajas y desventajas del uso de microservicio

3.5. Spring cloud y Netflix OSS

Spring Cloud es un nuevo proyecto de la familia spring.io con un conjunto de componentes que
se pueden usar para implementar nuestro modelo de operaciones. En gran medida, Spring
Cloud se basa en componentes de Netflix OSS. Spring Cloud integra los componentes de
Netflix en el entorno de Spring de una manera muy agradable utilizando la configuración
automática y la convención sobre la configuración similar a cómo funciona Spring Boot.
La siguiente tabla asigna los componentes genéricos en el modelo de operaciones a los
componentes reales que usaremos más adelante:

Componentes de operaciones Netflix OSS, Spring Cloud


Service Discovery server Netflix Eureka
Dynamic Routing and Load Balancer Netflix Ribbon
Circuit Breaker Netflix Hystrix
Monitoring Netflix Hystrix dashboard and Turbine
Edge Server Netflix Zuul
Central Configuration server Spring Cloud Config Server
OAuth 2.0 protected API’s Spring Cloud + Spring Security OAuth2
Centralized log analyses Logstash, Elasticsearch, Kibana
Tabla 3: Componentes operacionales

4. Comunicación de microservicios

Una regla importante en la arquitectura de microservicios es que cada microservicio debe


poseer sus datos y lógica de dominio. Del mismo modo que una aplicación completa posee su
lógica y datos, también cada microservicio debe tener su lógica y datos bajo un ciclo de vida
autónomo, con despliegue independiente de otros.

Esto significa que el modelo conceptual del dominio puede diferir entre subsistemas o
microservicios. Muchas aplicaciones empresariales de gestión de relaciones con los clientes
(CRM – Customer Relationship Management), los subsistemas de compras transaccionales y
los subsistemas de atención al cliente, utilizan cada uno atributos y datos particulares del
cliente, pero cada uno ve al cliente de una forma particular y emplea un sistema autónomo
diferente.

Por otro lado, el enfoque tradicional utilizado en muchas aplicaciones, es tener una base de
datos única y centralizada. A menudo se trata de una base de datos relacional normalizada que
se utilizara para toda la aplicación como se muestra en la Figura 2.
Figura 2: Comparación de la soberanía de datos: base de datos monolítica versus microservicios

Yendo aún más lejos, los microservicios diferentes podrían usar distintos tipos de base de
datos. Las aplicaciones modernas almacenan y procesan diversos tipos de datos y una base de
datos relacional no siempre es la mejor opción. Para algunos casos, una base de datos NoSQL
como MongoDB podría ser un modelo más conveniente y ofrecer un mejor rendimiento y
escalabilidad que un base de datos SQL como SQL server o MySql. Por lo tanto, las
aplicaciones basadas en microservicios a menudo usan una mezcla de base de datos SQL y
NoSQL, que a veces se denomina enfoque de persistencia poliglota
[https://martinfowler.com/bliki/PolyglotPersistence.html].

4.1. Tipos de comunicación

Los clientes y los servicios pueden tener distintos tipos de comunicación, cada una de los
cuales apunta a un escenario y objetivos diferentes. Inicialmente, esos tipos de comunicación
pueden clasificar en dos ejes o dimensiones.

El primer eje define si el protocolo es síncrono o asíncrono:

• Protocolo síncrono: HHTP es un protocolo síncrono. El cliente envía una petición


(request) y espera una respuesta (response) del servicio. Esto es independiente de la
ejecución del código del cliente, que podría ser síncrona (el hilo está bloqueado) o
asíncrona (el hilo no está bloqueado y la respuesta finalmente llegara a un callback – una
función que recibe el resultado). El punto importante aquí es que el protocolo
(HTTP/HTTPS) es síncrono y el código del cliente solo puede continuar su tarea cuando
recibe la respuesta del servidor HTTP.

• Protocolo asíncrono: Otros protocolos como AMQP (un protocolo admitido por muchos
sistemas operativos y entornos de nube) usan mensajes asíncronos. El código del cliente
o el remitente del mensaje generalmente no espera una respuesta. Simplemente envía el
mensaje como cuando se envía un mensaje a una cola de RabbitMQ o cualquier otro
intermediario de mensajes.

El segundo eje define si la comunicación tiene uno o múltiples receptores:

• Receptor individual: Cada petición debe ser procesada por exactamente un receptor o
servicio. Por ejemplo para esta comunicación es el patrón Command.

• Receptores múltiples: Cada petición se puede procesar por muchos o ningún receptor.
Este tipo de comunicación debe ser asíncrona. Por ejemplo es el mecanismo de
publicación/suscripción utilizado en los patrones como la arquitectura orientada a
eventos. Esto se basa en una interfaz de bus de eventos o agente de mensajes
(Message broker) al propagar actualizaciones de datos entre múltiples microservicios a
través de eventos; generalmente se implementa a través de un bus de servicio o
artefacto, mediante el uso de los temas y suscripciones del servicio.

Es bueno conocer estas dos dimensiones, para tener claridad sobre los posibles mecanismos
de comunicación, sin embargo, estas no son las preocupaciones importantes al desarrollar
microservicios. Ni la naturaleza asíncrona de la ejecución ni del protocolo seleccionado, son los
puntos importantes al integrar microservicios. Lo importante es poder integrar sus
microservicios de forma asíncrona, manteniendo la independencia entre ellos, como se explica
en la siguiente sección.
Figura 3: Patrones y anti-patrones en la comunicación entre microservicios

Se puede utilizar cualquier protocolo para comunicar y propagar datos de forma asíncrona
entre microservicios. Como se mencionó anteriormente, se podrían usar eventos de integración
con bus de eventos o un message broker o incluso, se podría usar HTTP polling hacia otros
servicios. En realidad, no importa. La importante es no crear dependencias síncronas entre los
microservicios.

En las secciones siguientes se explican los múltiples estilos de comunicación que se pueden
usar en una aplicación basada en microservicios.

4.2. Estilos de comunicación

Existen muchos protocolos y opciones que pueden usar, según el tipo de comunicación que se
requiera. Si se está usando un mecanismo basado en peticiones/respuesta síncrona, el
protocolo HTTP y el enfoque REST son los más comunes, especialmente si los servicios están
publicados fuera del host Docker o del cluster de microservicios. Para la comunicación interna
entre servicios, también pueden utilizar mecanismos de comunicación binarios, como la
comunicación remota de Service Fabric o WCF utilizando el protocolo TCP. Por otro lado
también se pueden usar mecanismos asíncronos basados en mensajes como AMQP.

Se puede usar un formato no estándar para la comunicación interna entre los microservicios, si
trabaja dentro de un host Docker o clúster de microservicio o para aplicaciones cliente
propietario que hablen con los microservicios.
4.2.1. Comunicación con HTTP y REST

Cuando un cliente usa la comunicación petición/respuesta, envía una petición a un servicio,


luego el servicio procesa y envía una respuesta. La comunicación petición/respuesta es
especialmente adecuada para consultar datos de una interfaz de usuario en tiempo real desde
las aplicaciones cliente. Por lo tanto, en una arquitectura de microservicio probablemente usara
este mecanismo de comunicación para la mayoría de las consultas, como se muestra en la
siguiente Figura 4.

Figura 4: Usando comunicación por petición/respuesta HTTP (síncrona o asíncrona)

Cuando un cliente usa la comunicación de petición/respuesta, supone que la respuesta llegará


en un tiempo corto, generalmente menos de un segundo o unos pocos segundos como
máximo. Para las respuestas con demora, se debe implementar una comunicación asíncrona
basada en patrones de masajes y tecnologías de mensajería, que es un enfoque diferente.

Un estilo arquitectónico popular para la comunicación petición/respuesta es REST. Este


enfoque se basa en el protocolo HTTP y está estrechamente relacionado con ello; comprende
de verbos HTTP como GET, POST, PUT y DELETE. REST es el enfoque de comunicación que
se utiliza con más frecuencia al crear servicios.

4.2.2. Comunicación en tiempo real

Entre otra posibilidad generalmente para usos diferentes de REST es una comunicación en
tiempo real y uno a muchos con frameworks de nivel superior como Spring Boot y protocolos
como WebSockets.
Como se muestra en la siguiente figura 5, la comunicación HTTP en tiempo real significa que el
servidor puede enviar el contenido a los clientes conectados, a medida que los datos estén
disponibles, en lugar de que el servidor espere las peticiones de nuevos datos por los clientes.

Figura 5: Comunicación asíncrona por mensaje en tiempo real uno-a-muchos

Dado que la comunicación se realiza en tiempo real, las aplicaciones cliente muestran los
cambios casi instantáneamente. Esto generalmente es manejado por un protocolo como
WebSockets, usando muchas conexiones, una por cliente. Un ejemplo típico es cuando un
servicio comunica un cambio en el puntaje de un juego de deportes a muchas aplicaciones web
cliente simultáneamente.

4.2.3. Comunicación basada en mensajes asíncronos

La mensajería asíncrona y la comunicación orientada a eventos, son fundamentales cuando se


propagan cambios entre múltiples microservicios a sus modelos de dominio relacionados. Los
modelos (Usuario, Cliente, Producto, Cuenta, etc.) pueden significar diferentes cosas para
diferentes microservicios. Eso significa que cuando se producen cambios, se necesita alguna
forma de reconciliar los cambios en los diferentes modelos. Una solución es la consistencia
eventual y la comunicación basada en eventos basada en mensajes asíncronos.

Una de las reglas más importantes que se debe seguir, en la medida de lo posible, es usar solo
mensajes asíncronos entre los servicios internos y usar comunicación síncrona solo desde las
aplicaciones cliente a los servicios de interfaz de usuario (API Gateway más el primer nivel de
microservicios).

Hay dos tipos de mensajería asíncrona: comunicación basada en mensajes de receptor único o
en mensajes de receptores múltiples. En las siguientes secciones entraremos en detalles sobre
ellos.

4.2.3.1. Comunicaciones de receptor único

La comunicación asíncrona basada en mensajes con un receptor único, significa que hay una
comunicación punto a punto que envía un mensaje a exactamente uno de los consumidores
que está leyendo desde el canal y que el mensaje se procesa solo una vez. Sin embargo, hay
situaciones especiales.

Por ejemplo, en un sistema en la nube que intenta recuperarse automáticamente de fallas, el


mismo mensaje podría enviarse varias veces. El cliente debe poder volver a intentar el envió de
mensajes en caso de fallos y el servidor debe implementar la lógica necesaria para que una
operación sea independiente, para que cada mensaje solo se procese una vez.

La comunicación basada en mensajes de un receptor único, es especialmente adecuada para


enviar comandos asíncronos de un microservicio a otro, como se muestra en la Figura 6 que
ilustra este enfoque.

Figura 6: Un microservicio recibiendo un mensaje asíncrono


4.2.3.2. Comunicación de receptores múltiples

Para lograr un enfoque más flexible, también se puede usar un mecanismo de


publicación/suscripción para que un mensaje del remitente esté disponible para los
microservicios subscriptores o para aplicaciones externas. Esto le ayuda a seguir el principio
open/closed en el servicio de envió. De esta forma, se pueden agregar suscriptores adicionales
en el futuro sin la necesidad de modificar el servicio del remitente.

Un punto importante es que se puede necesitar comunicación con múltiples microservicios que
están suscritos al mismo evento. Para hacerlo, se pueden usar los mensajes de
publicación/suscripción basados en eventos, como se muestra en la Figura 7. Este mecanismo
de publicación/suscripción no es exclusivo de la arquitectura de microservicios. Es similar a la
forma en que propagan las actualizaciones desde la base de datos de escritura hacia la base
de datos de consulta en el patrón arquitectónico Command and Query Responsibility
Segregation (CQRS). El objetivo es tener una consistencia eventual entre múltiples fuentes de
datos en un sistema distribuido.

Figura 7: Comunicación asíncrona por mensaje basada en eventos

Cuando se usa un bus de eventos, se puede usar un nivel de abstracción (como una interfaz de
bus de eventos) basado en una implementación usando la API de un message broker como
RabbitMQ. También se puede usar un bus de servicio de nivel superior como NServiceBus,
MassTransit o Brighter para coordinar el bus de eventos y el sistema de
publicación/suscripción.
5. Proceso de desarrollo
Como se mencionó en secciones anteriores, se puede hacer uso del Framework Spring Cloud y
Spring Boot para el desarrollo del proyecto ya sea open source para desarrollar aplicaciones en
contenedores Docker. Se puede desarrollar en Java cuando se apunta a contenedores Linux o
Windows, dependiendo de cuál Framework se utilice.

5.1. Flujo de trabajo

El ciclo de vida de desarrollo de la aplicación comienza en la máquina de cada desarrollador,


donde se codifica la aplicación con el lenguaje preferido y se prueba localmente.
Independientemente del lenguaje, el framework y la plataforma elegida, con ese flujo de
trabajo, el desarrollador siempre desarrolla y prueba contenedores Docker, pero lo hace de
forma local.

Cada contenedor (una instancia de una imagen Docker) incluye los siguientes componentes:

• El sistema operativo seleccionado (Linux, Windows Server).


• Los ficheros agregados por el desarrollador.
• Información de configuración del entorno y dependencias.

Esta sección describe el flujo de trabajo del bucle interno para el desarrollo de aplicaciones
basadas en contenedores Docker. El bucle interno significa que no tiene en cuanta el flujo de
trabajo de DevOps más amplio (que puede incluir hasta el despliegue en producción) y solo se
centra en el trabajo de desarrollo realizado en la máquina del desarrollador. No se incluyen el
paso inicial para configurar el entono, ya que se realizan solo una vez.

Una aplicación se compone de los servicios propios más las librerías adicionales. Los
siguientes son los pasos básicos que por lo general son necesarios para construir una
aplicación Docker, como se ilustra en la Figura 8.
Figura 8: Flujo de trabajo, paso-a-paso para desarrollar aplicaciones Docker contenerizadas

5.2. Microservicios con Spring Boot

Spring es un framework basado en Java el cual es el más popular para crear aplicaciones
empresariales. El framework Spring Boot proporciona un ecosistema de proyectos para abordar
las necesidades de aplicaciones modernas, como seguridad, acceso simplificando a las bases
de datos relacionales y No relacionales, procesamiento por lotes, integración con sitios de
redes sociales, procesamiento de flujos de datos, etc. Como Spring es un framework muy
flexible y personalizable, generalmente hay varias formas de configurar la aplicación. Aunque
es bueno tener múltiples opciones.

Spring Boot resuelve el problema de aplicaciones que necesitan una configuración compleja
mediante el uso de su poderoso mecanismo de configuración automática.

Spring Boot se centra en la configuración e integración de las dependencias que solemos


necesitar de forma genérica para que sin ningún esfuerzo empecemos directamente a
desarrollar nuestra aplicación. Incluso configura de forma embebida un servidor Tomcat o Jetty
si así lo deseamos. Y los mejor de todo es que no supone una limitación ya que podemos
seguir realizando cualquier configuración de igual forma que si no tuviéramos Spring Boot.

5.2.1. Spring Boot Starters


Spring Boot ofrece módulos de inicio para comenzar rápidamente con muchas de las
tecnologías de uso común, como Spring MVC, JPA, MongoDB, Spring Batch, Spring Security,
ElasticSearch y otros. Estos arrancadores están pre-configurados con las dependencias de
librerías más utilizadas. No es necesario buscar las versiones de las librerías compatibles y
configurarlas manualmente.

Spring Framework simplifica el uso de la inyección de dependencias para proporcionar la


configuración y administración de referencia a los objetos creados. También proporciona un
contenedor liviano, por ejemplo Spring Core, este contenedor le permite inyectar objetos
requeridos en otros objetos la inyección en Spring se realiza mediante inyección de
dependencias.

5.2.2. Spring Boot Autoconfiguración


Spring Boot resuelve el problema de que las aplicaciones cuales necesitan una configuración
compleja al eliminar la necesidad de configurar manualmente. Spring Boot toma una opinión
sobre la aplicación y configura varios componentes automáticamente, registrando Beans en
función de varios criterios, los cuales son:

• Disponibilidad de una clase particular.


• Presencia de una propiedad del sistema.
• Ausencia de un archivo de configuración.

5.2.3. Gestión de la configuración elegante


Spring admite la externalización de propiedades configurables mediante la configuración de
@PropertySource. Spring Boot lo lleva aún más lejos usar valores predeterminados y el
poderoso enlace de propiedades de tipo seguro a las propiedades de Beans.

5.2.4. Soporte de contenedor de servlets integrado fácil de usar


Tradicionalmente, al crear aplicaciones web, necesita crear módulos de tipo WAR o JAR y
luego implementarlos en servidores externos como Tomcat, WildFly y otros. Pero al usar Spring
Boot, puede crear un módulo de tipo JAR e incrustar el contenedor de servlets en la aplicación
fácilmente para que la aplicación sea una unidad de despliegue autónoma. Además, durante el
desarrollo, puede ejecutar con facilidad el módulo de tipo Spring Boot JAR como cualquier
aplicación Java.

5.2.5. Creando una aplicación Spring Boot


Spring Start es una página web el cual provee la creación de un proyecto y la principal
característica es la configuración del proyecto, para lo cual, se solicita los datos básicos del
proyecto como se muestra en la siguiente Figura 9.
Figura 9: Spring Initializer.

Como se puede observar en la anterior figura, que es posible crear un proyecto basado en
Maven o Gradle, también se puede definir el lenguaje del proyecto el cual puede ser Java,
Kotlin o Grovy, también se elige la versión de Spring Boot y el namespace además del nombre
del proyecto, adicionalmente se puede seleccionar las dependencias del proyecto.

En la sección de Spring Boot demuestra las versiones más actuales que prefiera conveniente,
también demuestra el buscador de las dependencias que desee utilizar en su nuevo proyecto,
una vez configurado el proyecto, con la opción “Generate the project”, iniciara la descarga
respectiva del proyecto pre-configurado, el cual se podrá importar en cualquier IDE de soporte
Maven o Gradle.

5.2.6. Spring Boot desde IDE


Desde el IDE de jetbrain IDEA podemos crear una aplicación Spring Boot con la utilización de
Spring initializer. Al igual que el uso de su página web lo primero que se realiza es la
configuración de la aplicación Spring Boot como se puede apreciar en la Figura 10.
Figura 10: IDEA JetBrains creando una aplicación Spring Boot.

5.3. Spring Cloud: Diseñando la arquitectura de microservicio

Al construir una arquitectura de microservicios, el arquitecto de un proyecto se centra en tres


tareas clave:

• Descomponiendo el problema del negocio.


• Estableciendo granularidad del servicio.
• Definiendo las interfaces de servicio.

5.3.1. Spring Cloud servidor de configuración

En un momento u otro, un desarrollador se verá obligado a separar la información de


configuración de su código. Muchos desarrolladores utilizarán un archivo de clase de
constantes en su aplicación para ayudar a centralizar toda su configuración en un solo lugar.
Los datos de configuración de la aplicación son escritos directamente en el código, a menudo
problemático porque cada vez que se debe hacer un cambio en la configuración.

La aplicación tiene que ser recompilada y/o redistribuida. Para evitar esto, es aconsejable
separará completamente la información de configuración del código de la aplicación. Esto
facilita la realización de cambios en la configuración sin pasar por un proceso de compilación,
pero también introduce complejidad porque ahora tiene otro artefacto que necesita ser
administrado y desplegado con la aplicación.

La administración de la configuración para un microservicio ocurre durante la fase de arranque


del microservicio. Como un recordatorio, la Figura 11 muestra el ciclo de vida del microservicio.

Figura 11: Los datos de configuración de la aplicación se leen durante la fase de arranque del servicio.

5.3.1.1. Construir servidor de configuración

El servidor de configuración de Spring Cloud es una aplicación basada en REST implementada


con Spring Boot; No viene como un servidor independiente. En su lugar, puede optar por alojar
en una aplicación existente de Spring Boot o inicie un nuevo proyecto de Spring Boot con el
servidor incorporado.

En la Figura 12 se ocupa de declarar las dependencias específicas de Spring Cloud que usará
en el servicio. La primera dependencia es el spring-cloud-starter-config, el cual es usado para
todos los proyectos Spring Cloud. La segunda dependencia es el spring-cloud-config-server
arrancador del proyecto.
Figura 12: Configuración del pom.xml para el servidor de configuración de Spring Cloud

5.3.1.2. Configurar el servidor de configuraciones

Lo primero que debe hacer es configurar un nuevo directorio, el cual será de almacenaje de los
archivos de configuración de los microservicios.

Este archivo es de tipo application.yml mencionara la configuración del servicio indicando el


puerto a escuchar y dónde ubicar la persistencia, back-end o base de datos; que servirá los
datos de configuración.

El parámetro importante en la entrada de configuración es el atributo ${location.configFiles}.


Este atributo como se puede apreciar en la Figura 13, proporciona una lista de configuraciones
de los datos de los microservicios.
Figura 13: El archivo application.properties de la configuración de Spring Cloud

5.3.1.3. Configurar la clase Bootstrap

Esta clase de bootstrap contendrá dos cosas: un método main() de Java que actúa como punto
de entrada para el inicio del Servicio y un conjunto de anotaciones de Spring Cloud que le
indican al servicio de inicio para qué tipo de comportamientos de Spring Cloud se lanzará el
servicio, como se puede apreciar en la Figura 14.

La anotación @EnableConfigServer habilita el servicio como un servicio Spring Cloud Config.

Figura 14: La clase de arranque para el servidor Spring Cloud Config


5.3.2. Spring Cloud servicio Discovery

Para comenzar sobre la arquitectura del servicio Discovery, necesitamos entender cuatro
conceptos. Estos conceptos generales se comparten en todas las implementaciones de dicho
servicio:

• Registro de servicio: ¿cómo se registra un servicio con el agente de detección de


servicios?

• Búsqueda de cliente de la dirección del servicio: ¿Cuáles son los medios por los cuales
un cliente del servicio busca información sobre el servicio?

• Intercambio de información: ¿Cómo se comparte la información de servicio entre nodos?

• Supervisión de estado: ¿cómo comunican los servicios su estado de salud al agente de


descubrimiento de servicios?

Figura 15: El equilibrio de carga del lado del cliente almacena en caché la ubicación de los servicios

5.3.2.1. Construir el servicio de Spring Eureka

En esta sección, configurará nuestro servicio Eureka propio de Netflix OSS utilizando Spring
Boot. Al igual que el servicio de configuración de Spring Cloud, la configuración de un servicio
Spring Cloud Eureka comienza con la construcción de un nuevo proyecto de Spring Boot y la
aplicación de anotaciones y configuraciones. Comencemos con su Maven pom.xml.

La siguiente Figura 16 el cual muestra las dependencias de servicio de Eureka que necesitará
para el proyecto Spring Boot que está configurando.
Figura 16: Configuración del pom.xml para el servicio de Eureka de Spring Cloud

5.3.2.2. Configurar el servicio Eureka

Cada servicio registrado con Eureka tendrá dos componentes asociados: el ID de la aplicación
y el ID de la instancia. El ID de la aplicación se utiliza para representar una instancia de servicio
de grupo. En un microservicio basado en Spring-Boot, el ID de la aplicación siempre será el
valor establecido por la propiedad spring.application.name. Para el servicio de su organización,
su spring.application.name se denomina creativamente servicio de organización. El ID de
instancia será un número aleatorio destinado a representar una única instancia de servicio.
Figura 17: El archivo application.properties del servicio Eureka de Spring Cloud

5.3.2.3. Configurar la clase Bootstrap

El registro de los servicios individuales tardará hasta 30 segundos en aparecer en el servicio de


Eureka ya que requiere tres pings de latidos del servicio separados por 10 segundos antes de
que diga que el servicio está listo para su uso. Para el servicio Eureka, la aplicación y su clase
bootstrap o clase principal. La siguiente Figura 18 muestra dónde agregar sus anotaciones.

Figura 18: La clase de arranque para el servicio Spring Cloud Eureka

Solo usa una nueva anotación para decirle a su servicio que sea un servicio de Eureka; el cual
es @EnableEurekaServer. En este punto, puede iniciar el servicio Eureka ejecutando el mvn
spring-boot: ejecute el JAR o ejecute docker-compose para iniciar el servicio. Una vez que se
ejecuta este comando, tendrá un servicio Eureka en ejecución sin servicios registrados en él.

5.3.3. Servicio de enrutamiento con Spring Cloud y Zuul

En una arquitectura distribuida como una de microservicios, véase la Figura 19; llegará un
punto en el que deberá asegurarse de que se produzcan comportamientos clave como la
seguridad, el registro y el seguimiento de los usuarios en múltiples llamadas de servicio. Para
implementar esta funcionalidad, deseará que estos atributos se apliquen de manera consistente
en todos sus servicios sin la necesidad de que cada equipo de desarrollo cree sus propias
soluciones.
Spring Cloud se integra con el proyecto de código abierto Zuul de Netflix. Zuul es una puerta de
enlace de servicios que es extremadamente fácil de configurar y usar a través de las
anotaciones de Spring Cloud. Zuul ofrece una serie de capacidades, incluyendo

• Mapeo de las rutas de todos los servicios en su aplicación a una única URL (cada punto
final del servicio obtiene su propia asignación de rutas).

• Creación de filtros que pueden inspeccionar y actuar sobre las solicitudes que llegan a
través de la puerta de enlace.

Para comenzar con Zuul, se presentan tres acontecimientos:

1. Configure un proyecto Zuul Spring Boot y configure las dependencias apropiadas de


Maven.
2. Modifique su proyecto Spring Boot con las anotaciones de Spring Cloud para decirle
que será un servicio de Zuul.
3. Configure Zuul para comunicarse con Eureka (opcional).

Figura 19: Arquitectura del servicio Gateway usando los servicios de registros y configuraciones

5.3.3.1. Construir el servicio de Spring Gateway

Para construir un servidor Zuul, debe configurar un nuevo servicio Spring Boot y definir las
dependencias de Maven correspondientes. Afortunadamente, poco se necesita para la
configuración de Zuul en Maven, Solo necesita definir una dependencia en su archivo pom.xml:
spring-cloud-starter-zuul, como se puede apreciar en la Figura 21; esta dependencia le dice al
framework Spring Cloud que este servicio se ejecutará Zuul e inicializa a Zuul apropiadamente.

5.3.3.2. Configurar el servicio Gateway

En el caso de una arquitectura de microservicios, Zuul toma un microservicio llama desde un


cliente y lo reenvía al servicio posterior. El cliente del servicio piensa que solo se está
comunicando con Zuul. Para que Zuul se comunique con los clientes posteriores, Zuul deben
saber cómo asignar la llamada entrante a una ruta descendente. Zuul tiene varios mecanismos
para hacer esto, incluyendo la configuración de la clase bootstrap, véase la Figura 20.

• Mapeo automatizado de rutas a través del descubrimiento del servicio.

• Mapeo manual de rutas utilizando el descubrimiento de servicios.

• Mapeo manual de rutas utilizando URLs estáticas

Figura 20: La clase de arranque para el servicio Spring Cloud Gateway


Figura 21: Configuración del pom.xml para el servicio Gateway de Spring Cloud
Figura 22: El archivo application.properties del servicio Gateway de Spring Cloud

5.3.4. Bus de eventos


Un bus de eventos permite la comunicación de tipo publicación/suscripción entre microservicios
sin que los componentes se tengan en cuenta explícitamente entre sí, como se puede apreciar
en la Figura 23.

Figura 23. Aspectos básicos de publicación/suscripción con un bus de eventos

5.3.4.1. El intermediario: RabbitMQ


Un intermediario de mensajes puede actuar como intermediario para diversos servicios. Se
pueden usar para reducir las cargas y los tiempos de entrega de los servidores de aplicaciones
web, ya que las tareas, que normalmente tardarían un poco en procesarse, pueden delegarse a
un tercero cuyo único trabajo es realizarlas.

La cola de mensajes permite a los servidores web responder a las solicitudes de forma rápida
en lugar de verse obligados a realizar en el lugar procedimientos con muchos recursos.

El consumidor puede tomar un mensaje de la cola e iniciar el procesamiento de la solicitud al


mismo tiempo que el productor está poniendo en cola nuevos mensajes en la cola.
5.3.4.2. RabbitMQ y conceptos de servidor

Aquí hay algunos conceptos importantes que deben describirse para profundizar en RabbitMQ.
El cual es bueno tener una idea de lo que es.

Articulo Conceptos

Productor Aplicación que envía los mensajes.

Consumidor Aplicación que recibe los mensajes.

Cola Buffer que almacena mensajes.

Mensaje Información que se envía del productor a un consumidor a través


de RabbitMQ.

Conexión Una conexión es una conexión TCP entre su aplicación y el


agente RabbitMQ.

Canal Un canal es una conexión virtual dentro de una conexión. Cuando


está publicando o consumiendo mensajes de una cola, todo se
hace a través de un canal.

Intercambio Recibe mensajes de los productores y los empuja a colas según


las reglas definidas por el tipo de intercambio. Para recibir
mensajes, una cola debe estar vinculada a al menos un
intercambio.

Enlace Un enlace es un enlace entre una cola y un intercambio.

Clave de enrutamiento La clave de enrutamiento es una clave que el intercambio analiza


para decidir cómo enrutar el mensaje a colas. La clave de
enrutamiento es como una dirección para el mensaje.

AMQP AMQP (Advanced Message Queuing Protocol) es el protocolo


utilizado por RabbitMQ para la mensajería.

Usuarios Es posible conectarse a RabbitMQ con un nombre de usuario y


contraseña dados. A cada usuario se le pueden asignar permisos
tales como derechos para leer, escribir y configurar privilegios
dentro de la instancia. A los usuarios también se les pueden
asignar permisos a hosts virtuales específicos.
Vhost, host virtual Un host virtual proporciona una forma de segregar aplicaciones
usando la misma instancia de RabbitMQ. Los diferentes usuarios
pueden tener diferentes privilegios de acceso a diferentes vhost y
se pueden crear colas e intercambios, por lo que solo existen en
un vhost.
Tabla 4: Conceptos Básicos de RabbitMQ

5.4. Infraestructura de persistencia

Cuando se utiliza base de datos relacionales como MySQL, SQL Server, Oracle o PostgreSQL,
un enfoque recomendado es implementar la capa de persistencia simplificando las
transacciones en su base de datos.

Cuando se utiliza una base de datos orientada a documentos, se implementa un agregado


como un documento único, serializado en JSON u otro formato. Sin embargo, el uso de la base
de datos es transparente desde el punto de vista de un código de modelo de dominio. Al usar
una base de datos NoSQL, todavía está usando clases de entidad y clases raíz de agregados,
pero con más flexibilidad.

Para nuestro caso se tendrá una arquitectura basada en microservicios para la infraestructura
de la persistencia y de la misma manera para la infraestructura de los servicios del proyecto,
para ello se puede apreciar la Figura 24.

Figura 24: Infraestructura de comunicación del Servicio y la Persistencia.


Con la arquitectura basada en microservicio implementada para la persistencia, comprenderá
de un servicio de configuración, servicio de registro o Eureka y el servicio de enrutamiento o
Gateway como se mencionó anteriormente, de esa manera podemos observar la Figura 25,
donde nos encontramos con tres microservicios los cuales cumplirán con la funcionalidad de
persistir los datos en una comunicación obstante con su respectivo servicio.

Figura 25: Servicio de registro o Eureka de la persistencia.

5.4.1. Construir el microservicio de la persistencia

La implementación de un microservicio para la arquitectura de la persistencia no es de gran


dificultad, gracias al framework de Spring Cloud. Para este caso implementaremos la
persistencia de Explanations, comenzando con la configuración del Pom.xml de dicho proyecto;
para ello se puede apreciar la Figura 26, demostrando las dependencias sobresalientes del
Config y Eureka para la creación de un microservicio.

Figura 26: Configuración del pom.xml para la persistencia de Explanations


Cada microservicio implementado para el registro al eureka, como se mencionó anteriormente,
es necesario establecer dos ID; el nombre de la aplicación y el puerto el cual se ejecutara dicho
servicio, entre otras configuración se tiene la conexión a su respectiva base de datos, como se
muestra en la Figura 27 y Figura 28.

Figura 27: Archivo de configuración para la persistencia de Explanations

Figura 28: Comunicación con el Config para la persistencia de Explanations

Los pasos anteriores se deberán contemplar la lógica de creación de microservicios para


futuras persistencias registradas, para nuestro caso los microservicios de Notifications y
Security se implementan de la misma manera. Ahora procedemos con la implementación de la
clase Bootstrap, como se muestra en la Figura 29, donde las anotaciones
@EnableDiscoveryClient realizara el registro en el servicio de Eureka.
Figura 29: La clase de arranque para la persistencia de Explanations

De manera repetitiva, realizamos el mismo proceso para los siguientes microservicios como ser
de Notifications, Security y entre otros futuros microservicios interconectados en dicha
arquitectura de persistencia.

5.5. Contenerizando microservicios

Los contenedores Docker es un proyecto open-source para automatizar el despliegue de


aplicación como contenedores independientes y autosuficientes, que se pueden ejecutar en la
nube o en servidores internos. Docker es también una compañía que proporciona y desarrolla
esta tecnología, colaborando con varios proveedores de Linux, Windows y plataformas en la
nube, véase la Figura 30.

Figura 30: Contenedores desplegados en un entorno.

Las imágenes Docker pueden correr de forma nativa en Linux o Windows, sin embargo, las
imágenes solo se pueden ejecutar en host Linux, entendiendo host como un servidor o una
máquina virtual.
5.5.1. Terminología Docker

En esta sección se presentan los términos y definiciones que debe manejar antes de entrar en
profundidades con Docker.

Conceptos Terminología

La imagen contiene todas las dependencias


así como toda la configuración de despliegue
Imagen de Contenedor
y ejecución que será utilizada por el
contenedor en tiempo de ejecución. Una
imagen es inmutable, es decir, no se puede
modificar después de crearla.

Una instancia de una imagen (Docker Image).


Un contenedor representa la ejecución de una
Contenedor (Container)
sola aplicación, proceso o servicio. Están
formados por el contenido de la imagen
Docker, el entorno de ejecución y un conjunto
estándar de instrucciones.

Un elemento que se puede aplicar a las Etiqueta (Tag)


imágenes para identificar versiones o entornos
de destino.

Un fichero de texto que contiene instrucciones Dockerfile


sobre cómo construir la imagen Docker.

La acción de preparar una imagen Docker


según la información y contexto definido en su
Construir (Build)
Dockerfile, más los ficheros adicionales de la
carpeta donde se prepara la imagen. Para
preparar imágenes Docker se utiliza el
comando: docker build.

Una colección de imágenes Docker,


identificadas con una etiqueta para diferenciar
la versión. Algunos repositorios contienen
múltiples variantes de una imagen específica, Repositorio (Repo)
por ejemplo, imágenes con SDK (más
pesadas) o imágenes sólo con entorno de
ejecución (más livianas), etc.

Un registro público para gestionar imágenes y


trabajar con ellas. Docker Hub provee
Docker Hub
almacenamiento de las imágenes, registros
públicos y privados, así como web hooks,
triggers e integración con GitHub y Bitbucket.

Una herramienta de línea de comandos y un


fichero en formato YAML con metadata, para
definir y ejecutar aplicaciones de múltiples
contenedores. Se define una
aplicación Compose
basada en múltiples imágenes con uno o más
ficheros .yml, que pueden reemplazar
parámetros dependiendo del entorno.

Una colección de hosts Docker presentada


como si fuera un host Docker virtual único,
Cluster
para que una aplicación pueda escalar a
múltiples instancias de servicios, distribuidos
en múltiples hosts dentro del cluster.

Una herramienta que simplifica la gestión de


clusters y hosts Docker. Los orquestadores
Orquestador (Orchestrator)
permiten gestionar sus imágenes,
contenedores y hosts a través de interfaces
gráficas o de línea de comandos (CLI).
Tabla 5: Terminologías con Docker
55.2. Construyendo aplicaciones desde un contenedor

Otro beneficio de Docker es que puede construir su aplicación desde un contenedor pre-
configurado, como se muestra en la Figura 31, por lo que no necesita crear una máquina o
máquina virtual para construir su aplicación. Puede usar o probar ese contenedor ejecutándolo
en su máquina de desarrollo. Pero lo que es aún más interesante es que puede usar el mismo
contendor de compilación desde su proceso integración continua.

Figura 31: Compilando la aplicación en un contenedor de construcción.

Necesitamos estas dependencias en tiempo de compilación. Pero no queremos llevar esto en


tiempo de ejecución, porque haría innecesariamente grande la imagen. Primeramente se debe
realizar la empaquetación del mismo microservicio con el siguiente comando como se puede
apreciar en la Figura 32.

Figura 32: Ejecución del comando Maven.

Luego de la ejecución y demostrado que no presenta errores en la ejecución, se procederá con


la construcción del Contenedor con el microservicio, con el siguiente comando presentado en la
Figura 33.
Figura 33: Ejecución del comando de construcción del Docker

Entonces tendremos nuestro Docker construido y solo queda ejecutarlo, teniendo en cuenta
con la identificación de nombres únicos del contenedor, para nuestro caso la arquitectura de la
persistencia usaremos los contenedores de MySQL y MongoDB de igual manera con el
RabbitMQ. Podemos observar en la siguiente Figura 34; el comando de ejecución del Docker
con el microservicio.

Figura 34: Comando del ejecutador del contenedor.

El comando docker run requiere de las configuraciones de la arquitectura de Spring Cloud de


manera que el microservicio pueda registrarse y realice la comunicación adecuada con otros
servicio, para ello se especifica los puertos y dominios de los servicios de configuraciones y el
servicio de registro, para este microservicio trabaja con MySQL y se debe especificar la
contraseña del servidor de MySQL.

De ese modo se debe realizar con todos los microservicio como podemos apreciar en la
siguiente Figura 35, donde los servicio de la persistencia estarán ejecutados en base a
contenedores con las configuraciones apropiadas los cuales facilitan con Spring Cloud, como
conclusión se puede apreciar la Figura 25 del servicio de Eureka.
Figura 35: Visualizador de contenedores ejecutados.

5.6. Infraestructura de Servicios

Como se mencionó anteriormente, véase la Figura 24, la capa de aplicación o servicio se


puede implementar tanto como parte del artefacto que está construyendo, como dentro de un
proyecto de API Web o un proyecto de aplicación web Spring Boot. En el caso de un
microservicio creado con Spring Boot, la capa de aplicación generalmente será su librería API
Web. Normalmente se desea inyectar dependencias que implementen objetos de
infraestructura.

FeignClient es una librería para la creación de clientes de API REST de forma declarativa.
Entonces, en lugar de codificar manualmente los clientes para la API remota y tal vez usar
Spring RestTemplate declarando una definición de dicho cliente y el resto se genera durante el
tiempo de ejecución para su uso.

5.6.1. FeignClient con Spring Cloud

La forma más sencilla es incluir la configuración de Spring Cloud en la administración de


dependencias en el POM de Maven.
Primeramente se debe asegurar una versión compatible con Spring Cloud, véase la Figura 36
de igual manera con la versión Spring Boot, ya que ocasionará problemas de combatividad con
el Framework.

Figura 36: Dependencia administrativa de Spring Cloud.

Ahora, podemos agregar la dependencia a Feign con el arrancador clásico de Spring Boot
véase la Figura 37.

Figura 37: Dependencia de FeignClient de Spring Cloud.

Los FiegnClient utiliza un enfoque declarativo para acceder a la API. Para usarlo, primeramente
debemos habilitar el soporte de Spring Cloud en nuestra aplicación Spring Boot con la
anotación @EnableFeignClients en el nivel de clase Bootstrap, véase la Figura 38.

Figura 38: Configuración del FeignClient.

Para convertirlo en un cliente Feign, debemos establecer la anotación @FeignClient en la


interfaz y asignarle un nombre con el atributo name y también configurar la URL remota con el
atributo url, como se muestra en la Figura 39. En lugar de la URL, también podríamos usar el
descubrimiento de servicios usando Eureka.
Figura 39: Configuración del Cliente Feign.

Ahora, podemos inyectar el nuestro cliente con nuestro código como cualquier otro Spring
Bean. En el inicio, Spring Cloud configurara el cliente Feign para nosotros y nos dará un Spring
Proxy regular para que podamos comenzar a trabajar con el extremo remoto.

5.6.2. Implementando el patrón Command

El patrón de command es una solicitud para que el sistema realice una acción que cambie el
estado del sistema. Los comandos son imprescindibles y se deben procesar solo una vez.

Los comandos se pueden originar desde la interfaz del cliente Feign, como resultado de un
usuario que inicia una petición o desde un administrador de procesos, cuando este le está
pidiendo un agregar o actualizar para realizar dicha acción.

Es importante que solo se procese una vez. Un comando es idempotente si se puede ejecutar
varias veces sin cambiar el resultado, ya sea por la naturaleza del comando o por la forma en
que el sistema lo maneja.

Es una buena practica hacer que sus comandos y actualizaciones sean idempotentes, cuando
tenga sentido bajo las reglas en invariantes del negocio en su dominio. Por ejemplo, para el
comando CreateMessageCmd llega a su sistema varias veces, debe poder identificarlo y
asegurarse de no crear varias órdenes.

El siguiente ejemplo muestra la clase CrearMessageCmd. Este es un comando inmutable que


se utiliza en el microservicio del crear un mensaje específico, como se muestra a continuación.

La clase mencionada se encargara de realizar la petición de creación que lo realizara mediante


el cliente Feign como mencionamos anteriormente.
Clase de Creación DTO Clase del Comando Crear

Tabla 6: Construcción del patrón Command

5.6.3. Construir el microservicio

La implementación del microservicio para la arquitectura de servicio, de manera sencilla como


la implementación de la persistencia, usando el framework de Spring Cloud. Realizaremos de
manera independiente la implementación del servicio de configuración, el servicio de registros
(Eureka) y el servicio de enrutamiento (Gateway). Entonces teniendo claro la funcionalidad de
la arquitectura de los microservicios, continuaremos con la construcción del servicio de
Explanations.
Para ello se puede apreciar la Figura 40 explicando las dependencias necesarias para el
registro de nuestro servicio y comunicación con su respectiva persistencia.
Figura 40: Configuración POM del servicio Explanations

Se debe tomar en cuenta la compatibilidad con las versiones de Spring Boot y Spring Cloud,
cada microservicio implementado se registrara en el servicio de Eureka para ello en necesario
realizar la configuración adecuada para la intercomunicación del servicio, como se puede
apreciar en la Figura 41.
Figura 41: Configuración YML del servicio Explanations.

La arquitectura para los servicios se ha configurado en un ambiente independiente de la


persistencia ya que por ello permanece con los mismo puertos configurables, entonces de igual
manera con la persistencia se debe configurar la clase principal o Bootstrap del servicio, como
se puede apreciar la Figura 42, habilitando el servicio de Eureka y del Gateway.

Figura 42: La clase de arranque para el servicio de Explanations

De igual manera, con el resto de los servicios que presenta nuestro proyecto, cuando todos los
microservicios estén funcionando en una misma arquitectura, estarán registradas en el servicio
de Eureka de la siguiente manera, véase la Figura 43.
Figura 43: Servicio de Registro o Eureka de los servicios.

5.7. Infraestructura de la Interfaz de usuario

Como se presentó anteriormente, lo primero que se tiene que hacer en cada proyecto de
microservicio es agregar o crear los servicios de configuración, de registro y del enrutamiento,
básicamente independientes de otros microservicios.

La arquitectura de microservicios a menudo comienza con el manejo de los datos y la lógica del
lado del servidor. Sin embargo, un enfoque más avanzado es diseñar la interfaz de usuario (UI)
basada también en microservicios. Eso significa tener una interfaz de usuario compuesta
producida por los microservicios, en lugar de tener microservicios en el servidor y una
aplicación monolítica que consuma los microservicios. Con este enfoque, se pueden construir
microservicios completos, que incluyan tanto la lógica como la presentación visual.

Figura 44: Interfaz de usuario monolítica consumiendo microservicios de backend.


La Figura 44 muestra el enfoque más sencillo, que consiste simplemente en consumir
microservicios desde una aplicación cliente monolítico. Por supuesto, podría tener un servicio
Angular de por medio, generando el HTML y TypeScript. La figura es una simplificación donde
destaca que tiene una interfaz de usuario única, que consume los microservicios,, que solo se
enfocan en la lógica y los datos y no en la interfaz de usuario.

Figura 45: Configuración del ambiente de la comunicación con Backend.

En la Figura 45 se muestra la configuración donde se debe especificar los dominios y los


puertos donde se ejecutan cada servicio, esta configuración se verificara al momento de la
ejecución de la UI del Explanations, para ello se debe usar los siguientes comandos de la
Figura 46.
Figura 46: Comandos de ejecución de la Interfaz de usuario.

Para concluir, tenemos como resultado nuestro proyecto funcional con tres arquitecturas
basadas en microservicios intercomunicados de manera independientes o por capas a nivel de
persistencia, a nivel de servicios y de aplicación. Ahora se podrá realizar la visualización de
nuestra respectiva interfaz de usuario, como se puede apreciar en la Figura 47.

Figura 47: Visualización de la interfaz de usuario de Explanations.


6. Conclusiones

A la hora de construir nuestras aplicaciones Web, se recomienda utilizar los mecanismos de


API REST a través de microservicios, utilizar framework Spring Boot para la comunicación más
óptima entre aplicaciones, para luego administrarlas con mayor facilidad y mayor rendimiento.

La curva de aprendizaje del framework Spring Boot no es compleja y se tiene una gran
comunidad de desarrolladores, que ofrecen una amplia gama de librerías que aceleran la
construcción de microservicios. Además Spring Boot es open source.

La arquitectura de microservicios nos brinda muchas ventajas, entre las principales se tiene:

• El registro de microservicios esta basado en el patrón Service Registry, el cual es una


base fundamental en el desarrollo de microservicios. Para este fin se usa Eureka Netflix
por su simpleza y fácil implementación.
• Un API Gateway actúa como un proxy y balanceador de carga entre el cliente u los API
REST para evitar que los clientes interactúen directamente con los microservicios. Para
este fin se usa Zuul y Ngnix, donde Zuul destaca por ser más compatible con proyectos
de Spring.
• El cambio dinámico de las configuraciones usando el servidor de configuraciones que
facilita un recurso REST con las propiedades actualizadas.
• El ambiente complejo de microservicios, las pruebas se las realiza desde el inicio y a la
par del desarrollo de la aplicación.
• Es dificultoso el rastreo de las transacciones mediante la correlación de logs emitidos
por diferentes microservicios sin una herramienta que ayuda en el monitoreo.
• El despliegue continuo es el proceso de despliegue de aplicaciones a uno a varios
ambientes de producción, que están apropiadamente configurados. El
aprovisionamiento de infraestructura, la dockerizacion de microservicios y las
herramientas de automatización facilitan el despliegue continuo automatizado.
Bibliografía

Eureka Netflix. (2018, Octubre 21). service registration and discovery. Recuperado el Octubre
2018, de spring.io: https://spring.io/guides/gs/service-registration-and-discovery/

Create a base image. En la documentactión oficial de Docker


https://docs.docker.com/engine/userguide/eng-image/baseimages/

Chris Richardson. Pattern: Database per service http://microservices.io/patterns/data/database-


per-service.html

Charles Richardson. Pattern: API Gateway / Backend for Front-End


http://microservices.io/patterns/apigateway.html

Publish/Subscribe Channel
http://www.enterpriseintegrationpatterns.com/patterns/messaging/PublishSubscribeChannel.htm
l

Richardson, C. (2018, Octubre 5). microservices.io. Recuperado el Octubre 2018, de


https://microservices.io/patterns/apigateway.html

Hystrix. (2018, Octubre 21). circuit-breaker. Retrieved Octubre 2018, from spring.io:
https://spring.io/guides/gs/circuit-breaker/

Turnquist, G. L. (2017). Learning Spring Boot 2.0. Birmingham: Packt.

Dixon, J. (2017). Monitoring with Graphite. California: O'Reilly Media.

S-ar putea să vă placă și