Introducción
Estoy leyendo el libro Building Microservices de Sam Newman, publicado por O'Reilly. Este libro trata sobre las principales ventajas y desventajas de los microservicios, y si realmente es la arquitectura que deseas para tu sistema. Uno de los temas que aborda es cómo estos sistemas se comunican entre sí.

Portada del libro Building Microservices.
Partiendo del principio de que cada microservicio debe ser lo más independiente posible, puede parecer contradictorio decir que deben comunicarse. Si tomamos literalmente lo que dice el autor sobre el acoplamiento entre servicios, deberíamos procurar la menor comunicación posible.
Creo que es inevitable que nuestros servicios se comuniquen, y probablemente tú también lo creas si estás leyendo este artículo. Te mostraré las formas que aprendí en el libro y mi opinión sobre ellas.
Primero debemos entender que existen dos grandes categorías de comunicación: sincrónica bloqueante y asincrónica no bloqueante.
Sincrónica bloqueante
En esta categoría, un microservicio envía una solicitud a otro y espera una respuesta antes de continuar, manteniendo la operación bloqueada mientras tanto.
Si trabajas en el área o tienes experiencia, probablemente ya estás familiarizado con el patrón Request-Response, que es exactamente cómo funciona la comunicación sincrónica. Podemos usar HTTP o RPC.
No te confundas: aunque uses async
y await
en tu lenguaje de programación, esa comunicación sigue siendo bloqueante, ya que el uso de await
implica que esa línea debe completarse antes de continuar.
El acoplamiento aquí es bidireccional — ambos microservicios se comunican. En mi opinión, la principal desventaja es que, en caso de falla, no es fácil volver a intentarlo.
Asincrónica no bloqueante
En la comunicación asincrónica, un microservicio puede continuar su procesamiento sin esperar respuesta. Esto puede hacerse de varias maneras:
Request-Response
El concepto es similar a la comunicación sincrónica, pero aquí la respuesta se recibe de inmediato, independientemente de si el procesamiento ha terminado o no. También se pueden utilizar brokers con base en colas.
Orientado a eventos
En este estilo, un servicio simplemente emite el hecho de que ocurrió un evento, mientras que otros servicios escuchan estos eventos y sus datos (mensajes).
Hay bajo acoplamiento entre servicios, ya que un broker como RabbitMQ se encarga de recibir y transmitir los eventos. También se debate mucho qué información compartir en los eventos, ya que demasiada información puede aumentar el acoplamiento y los riesgos de breaking changes.
Comunicación por datos compartidos
Este es el estilo más controvertido — algunos argumentan que no es una verdadera comunicación. Consiste en modificar una tabla en una base de datos compartida entre dos microservicios, lo cual va en contra de la recomendación de que cada servicio tenga su propia base de datos. Pero es una discusión más compleja.
Este tipo de comunicación también puede hacerse mediante archivos compartidos, por ejemplo.
En mi opinión, este modelo no es tan malo como parece. Es simple y cumple su propósito: comunicar dos servicios.
¿Cuál debo elegir?
Como casi todo en IT, probablemente ya sabes la respuesta: ¡Depende!
Si tu sistema es simple y crees que puedes simplemente repetir una solicitud en caso de error, no hay nada de malo en usar un patrón sincrónico Request-Response. Pero si necesitas reintentar sin intervención del usuario, usar una cola para guardar las solicitudes es fundamental.
También creo que no debemos temer al cambio. Si tu sistema ha crecido y crees que es momento de cambiar el estilo de comunicación, evalúa si realmente habrá beneficios.
Toma decisiones basadas en lo que sea mejor para tu equipo (es decir, si dominan la tecnología) y en lo que aporte escalabilidad a tu aplicación — no solo por moda o preferencia personal.