Mi escenario es el siguiente.
Estoy diseñando un sistema diseñado para recibir datos de varios tipos de sensores, y convertirlos y luego persistir para que sean utilizados por varios servicios de front-end y análisis más adelante.
Estoy tratando de diseñar cada servicio para que sea lo más independiente posible, pero tengo algunos problemas. El equipo ha decidido un DTO que nos gustaría usar. Los servicios externos (destinatarios de datos del sensor) recibirán los datos de su propia manera única, luego los convertirán en un objeto JSON (el DTO) y los enviarán a Message Broker. Los consumidores de los mensajes sabrán exactamente cómo leer los mensajes de datos del sensor.
El problema es que estoy usando el mismo DTO en algunos servicios diferentes. Se debe implementar una actualización en varias ubicaciones. Obviamente, lo hemos diseñado de tal manera que algunos campos adicionales o faltantes en el DTO aquí y allí no sean un gran problema hasta que los servicios se hayan actualizado, pero todavía me molesta y me hace sentir que estoy cometiendo un error. Fácilmente podría convertirse en un dolor de cabeza.
¿Me estoy equivocando al diseñar el sistema? Si no, ¿cuáles son algunas formas de evitar esto, o al menos para aliviar mis preocupaciones?
proto
archivo para gRPC o elavro
esquema para Kafka y generar los DTO en ambos servicios, pero no compartiría una biblioteca compartida entre dos proyectos.Respuestas:
¿Mi consejo? No comparta estos DTO entre las aplicaciones en ningún tipo de biblioteca. O al menos no hagas esto ahora.
Lo sé, parece muy contrario a la intuición. Estás duplicando el código, ¿verdad? Pero esta no es una regla comercial, por lo que puede ser más flexible.
El servicio que envía el DTO debe ser rígido en su contrato de mensaje, como una API Rest. El servicio no puede cambiar el DTO de una manera que pueda romper los otros servicios que ya están consumiendo la información del DTO.
Cuando se agrega un nuevo campo a DTO, solo actualiza los otros servicios que consumen este DTO si necesitan el nuevo campo. De lo contrario, olvídalo. Al usar JSON como tipo de contenido, tiene la flexibilidad de crear y enviar nuevos atributos sin romper el código de los servicios que no asignan estos nuevos campos en sus versiones reales de DTO.
Pero si esta situación realmente te molesta, puedes seguir la regla de los tres :
Por lo tanto, intente esperar un poco más antes de compartir este DTO entre los servicios.
fuente
Cuando se trata de microservicios, los ciclos de vida de desarrollo de los servicios también deberían ser independientes. * *
Diferentes SLDC y diferentes equipos de desarrollo
En un sistema de EM real, podría haber varios equipos involucrados en el desarrollo del ecosistema, cada uno de los cuales está a cargo de uno o más servicios. A su vez, estos equipos pueden estar ubicados en diferentes oficinas, ciudades, países, planes ... Quizás, ni siquiera se conocen entre sí, lo que hace que compartir conocimiento o código sea muy difícil (si es posible). Pero esto podría ser muy conveniente porque el código compartido también implica una especie de razonamiento compartido y algo importante para recordar es que, lo que tenga sentido para un equipo específico, no tiene que hacerlo para otro equipo. Por ejemplo, dado el Cliente DTO , podría ser diferente dependiendo del servicio en juego, porque los clientes son interpretados (o vistos) de manera diferente a cada servicio.
Diferentes necesidades, diferentes tecnologías.
Los SLDC aislados también permiten a los equipos elegir la pila que mejor se adapte a sus necesidades. La imposición de DTO implementados en una tecnología específica limita la capacidad de los equipos para elegir.
Los DTO no son reglas comerciales ni contratos de servicios.
¿Qué son realmente los DTO? Objetos simples sin otro objetivo que mover datos de un lado a otro. Bolsas de captadores y colocadores. No es el tipo de "conocimiento" que vale la pena reutilizar, en general porque no hay ningún conocimiento en absoluto. Su volatilidad también los convierte en malos candidatos para el acoplamiento.
Contrariamente a lo que Dherik ha declarado, debe ser posible que un servicio cambie sus DTO sin tener que hacer que otros servicios cambien al mismo tiempo. Los servicios deben ser lectores tolerantes, escritores tolerantes y tolerantes a fallas . De lo contrario, provocan el acoplamiento de tal manera que la arquitectura del servicio no tiene sentido. Una vez más, y contrario a la respuesta de Dherik, si tres servicios necesitan exactamente los mismos DTO, es probable que algo haya salido mal durante la descomposición de los servicios.
Diferentes negocios, diferentes interpretaciones
Si bien podría haber (y habrá) conceptos transversales entre los servicios, no significa que tengamos que imponer un modelo canónico para obligar a todos los servicios a interpretarlos de la misma manera.
Caso de estudio
Digamos que nuestra empresa tiene tres departamentos, Servicio al Cliente , Ventas y Envíos . Digamos que cada uno de estos lanzamientos de uno o más servicios.
Servicio al cliente, debido a su lenguaje de dominio , implementa servicios en torno al concepto de clientes, donde los clientes son personas . Por ejemplo, los clientes se modelan como nombre , apellido , edad , sexo , correo electrónico , teléfono , etc.
Ahora, digamos, Ventas y Envíos modelan sus servicios de acuerdo con sus respectivos idiomas de dominio también. En estos idiomas, el concepto de cliente también aparece pero con una sutil diferencia. Para ellos, los clientes no son (necesariamente) personas . Para ventas , los clientes son una serie de documentos de una tarjeta de crédito y una dirección de facturación , para el envío de un nombre completo y una dirección de envío también.
Si obligamos a Ventas y envíos a adoptar el modelo de datos canónicos del Servicio al cliente , los estamos obligando a tratar con datos innecesarios que podrían terminar introduciendo una complejidad innecesaria si tienen que mantener toda la representación y mantener los datos del cliente sincronizados con el servicio al cliente. .
Enlaces relacionados
* Aquí es donde se encuentran los puntos fuertes de esta arquitectura
fuente
Deberías estar publicando eventos . Los eventos son cierto tipo de mensajes que representan un hecho sólido sobre algo que ha sucedido en un momento determinado.
Cada servicio debe tener una responsabilidad muy bien definida, y debe tener la responsabilidad de publicar los eventos relacionados con esa responsabilidad.
Además, desea que sus eventos representen eventos relacionados con el negocio, no eventos técnicos. Por ejemplo, prefiera un
OrderCancelled
evento a unOrderUpdated
constatus: "CANCELLED"
.De esa manera, cuando un servicio necesita reaccionar a una orden cancelada, solo necesita escuchar un tipo particular de mensaje, que solo contiene datos relevantes para ese evento. Por ejemplo, un
OrderCancelled
probablemente solo necesita unorder_id
. Cualquier servicio que necesite reaccionar a esto ya ha almacenado todo lo que necesita saber sobre el pedido en su propio almacén de datos.Pero si el servicio solo tuviera
OrderUpdated
eventos para escuchar, entonces necesitaría interpretar el flujo de eventos, y ahora dependía del pedido de entrega para concluir correctamente cuando se cancelaba un pedido.En su caso, sin embargo, como su están publicando datos de los sensores, podría tener sentido para tener un servicio, detectar los eventos y publicar una nueva corriente de "eventos de negocios", por ejemplo
TemperatureThresholdExceeded
,TemperatureStabilised
.Y tenga cuidado al crear demasiados microservicios. Los microservicios pueden ser una excelente forma de encapsular la complejidad, pero si no descubre los límites de servicio adecuados, su complejidad está en la integración del servicio. Y eso es una pesadilla para mantener.
Es mejor tener muy pocos servicios, demasiado grandes, que tener demasiados servicios demasiado pequeños.
fuente