Servicios composable
Con este enfoque, los servicios están diseñados para ser componentes autónomos, poco acoplados y de implementación independiente que exponen interfaces bien definidas.
Si esta definición te suena a microservicios, estas en lo cierto. Muchos de los problemas que han afectado el desarrollo y el uso de los microservicios pueden atribuirse a la falta de atención suficiente a la componibilidad ‘composable’ de los microservicios, no al patrón de los microservicios en sí.
El patrón de servicio composable se basa en la creación de aplicaciones a partir de servicios autónomos y reutilizables: cada servicio se centra en una capacidad funcional o comercial específica para que pueda desarrollarse, implementarse y escalar de forma independiente.
Estos servicios se comunican entre sí a través de solicitudes bien definidas o mensajes de eventos, lo que les permite trabajar juntos sin problemas dentro o entre procesos, y de forma sincrona o asíncrona.
¿Qué hace que un servicio sea composable?
Para ser considerado composable, un microservicio debe tener estas características:
- Sin estado y multiproceso: un servicio debe estar sin estado y capaz de procesar una sola solicitud o mensaje de evento con un solo hilo, optimizando su eficiencia. Debe permitir procesar varias solicitudes o eventos al mismo tiempo.
- Implementa un contexto delimitado por el dominio: cada servicio debe tener un alcance de dominio claro y centrarse en una capacidad funcional o comercial específica. El ámbito de dominio bien definido mejora la capacidad de implementación independiente y respeta los límites de propiedad y responsabilidad.
- Es reconocible: los servicios deben ser reconocibles los mensajes que entregan mensajes de solicitud y eventos. La capacidad de descubrimiento del servicio ayuda en la implementación de la autoconfiguración, la conmutación por error y el equilibrio de carga.
- Es reactivo: los servicios deben reaccionar a las solicitudes entrantes o los mensajes de eventos mediante la ejecución de la lógica, el envío de mensajes o la publicación de eventos. También pueden leer y escribir en el almacenamiento persistente si son servicios persistentes. Los servicios reactivos enfatizan la capacidad de respuesta, la escalabilidad, la resiliencia y la comunicación basada en mensajes.
- Utiliza mensajes autónomos: Toda la información requerida por el servicio para procesar un mensaje debe estar presente en el propio mensaje entrante o en un almacén de datos persistente. Los mensajes deben ser autodescriptivos y no requerir la complejidad adicional de un sistema de administración de esquemas separado. Los mensajes autónomos admiten mejor la autonomía del servicio, el acoplamiento flexible y la gestión de versiones.
- Utiliza una sola clase de servicio para el acceso a la entidad: el acceso a las entidades de datos persistentes debe realizarse a través de una sola clase de servicio dedicada a esa clase de entidad específica. Una única clase de servicio para una entidad de datos mejora la organización del código, la reutilización, el mantenimiento y la capacidad de prueba.
Orquestación de mensajes
Un orquestador de mensajes es un software que facilita el paso de mensajes entre componentes de software. Acepta mensajes en un formato entendido por el remitente y entrega mensajes en un formato entendido por el receptor.
Los orquestadores pueden enrutar de forma inteligente los mensajes de forma sincrónica a un solo destinatario como una solicitud con una respuesta esperada, o de forma asíncrona a los suscriptores a través de una cola de mensajes. Los orquestadores comparten las ubicaciones de todos tus componentes de servicio registrados entre ellos.
Un mensaje se puede entregar a través de una red, pero se entrega como una llamada de método si tanto el remitente como el receptor se encuentran dentro del mismo proceso de tiempo de ejecución.
En el ejemplo anterior, los mensajes M2 a M4 se originan en el Componente 1 y se envían a los componentes de destino (2, 3 y 4). Los mapas de las direcciones de los componentes se comparten automáticamente entre los orquestadores.
La segmentación vertical
Los agregados de servicios composable se pueden organizar como segmentos verticales, donde podemos implementar la partición del dominio, para que podamos dividir las cosas en términos de conocimiento del dominio de la aplicación y contextos limitados por el dominio.
El segmento vertical es un patrón que se repite en la mayoría de las funciones de la aplicación y corta un segmento a través de las capas, desde datos externos hasta datos persistentes. Los datos externos provienen de una interfaz de usuario, un dispositivo electrónico, una cola de eventos u otra aplicación.
Un corte vertical representa una estratificación lógica, pero no necesariamente física. Proporciona un punto de partida razonable para descomponer una característica de la aplicación en componentes ejecutables y las comunicaciones necesarias para conectarlos.
Los segmentos verticales se agregan con frecuencia para implementar características y funciones de aplicaciones más grandes, mientras que cada segmento continúa manteniendo su enfoque individual y la separación de preocupaciones.
La división vertical es una perspectiva útil para implementar una nueva funcionalidad de la aplicación y para modificar o rediseñar la funcionalidad existente. También es sinérgico con las prácticas modernas de desarrollo, como el desarrollo basado en el comportamiento y el diseño basado en el dominio.
El contexto delimitado por el dominio
El concepto de diseño controlado por dominio de un contexto delimitado por dominio es crucial para definir servicios composable individuales que no entren en conflicto con los servicios desarrollados por diferentes equipos.
Un dominio es “una esfera específica de actividad o conocimiento”. Debido a que estamos hablando de desarrollo de software, probablemente sea una buena idea agregar también las palabras propiedad y responsabilidad .
¿Cómo trazamos límites de dominio en torno a un contexto? Como desarrolladores de software, debemos descomponer aplicaciones grandes y complejas en componentes ejecutables con los que podemos construir sistemas de software completos. Si no podemos identificar los límites de los dominios utilizables, tendremos dificultades para crear software composable.
Dividir una aplicación en componentes efectivos y utilizables es probablemente el desafío más crítico y más difícil en el diseño de software. Tenemos que empezar en alguna parte:
- Una aplicación se compone de componentes que interactúan mediante mensajería síncrona y asíncrona.
- Cada componente de la aplicación existe dentro de su propio contexto delimitado por el dominio.
- Un contexto se compone de los datos que representan su estado y la lógica y las reglas que gobiernan ese estado.
- Los componentes y, por lo tanto, los contextos, se pueden agregar a componentes y contextos más complejos.
- El contexto de una aplicación es el agregado de los contextos de todos sus componentes.
La palabra componente significa “una parte o elemento de algo mayor” . En este caso, es una parte de un sistema de software que se puede compilar e implementar de forma independiente, describe el estado, las reglas y la lógica de un contexto limitado y expone una interfaz de programación a través de la cual otros componentes pueden interactuar con él.
Dividir un contexto acotado se refiere a dividir un dominio grande y complejo en partes más pequeñas y manejables. Los contextos acotados representan un límite alrededor de un conjunto cohesivo de modelos de dominio y reglas comerciales. Puede ser necesario dividir un contexto delimitado cuando se vuelve demasiado grande o difícil de manejar para reutilizarlo, mantenerlo, comprenderlo o evolucionar de manera efectiva.
No tengas miedo a la hora de dividir un dominio complejo en subdominios más atómicos, reutilizables y manejables que se puedan agregar para implementar dominios más complejos. Esto es especialmente importante cuando se implementan dominios que actúan sobre varias entidades de datos persistentes.
Conclusión
Una vez que conectas un orquestador de mensajes a un servicio composable se convierte en parte de la aplicación y, sujeto a las restricciones de seguridad aplicables, puede enviar y recibir mensajes, publicar y suscribirse a eventos, y unirse sin problemas a la funcionalidad del sistema de la aplicación.
Esta estructura descentralizada proporciona resiliencia y solidez. Cuando no se puede acceder a algún servicio, la solicitud se puede redirigir automáticamente a una instancia accesible del servicio. Es un enfoque muy rentable para crear aplicaciones que sean funcionalmente ricas, eficaces, resistentes y extensibles.