architecture - monolithic - microservices tutorial
Compartir código y esquema entre microservicios (4)
Si elige una arquitectura de microservicios en su organización, pueden compartir la configuración a través de zookeeper o su equivalente. Sin embargo, ¿cómo deberían los diferentes servicios compartir un esquema db común? constantes comunes? y servicios comunes?
Una forma sería colocar todos los microservicios en el mismo repositorio de código, pero eso estaría en contradicción con el desacoplamiento que viene con los microservicios ...
Otra forma sería hacer que cada microservicio fuera completamente independiente, sin embargo, eso causaría duplicación de código y duplicación de datos en las bases de datos separadas que cada microservicio debería tener.
Otra forma sería implementar microservicios funcionales sin contexto / state, pero normalmente no es realista e impulsaría la arquitectura a tener un hub central que mantenga el contexto / state y mucho tráfico desde / hasta él.
¿Cuál sería una forma escalable, eficiente, práctica y, con suerte, hermosa de compartir códigos y esquemas entre microservicios?
Con respecto al código común, la mejor práctica es usar un sistema de empaque. Entonces, si usas Java, usa maven, si usas Ruby y Gems, si python y luego pypi, etc. Idealmente, un sistema de empaquetamiento agrega poca fricción así que puedes tener un repositorio (por ejemplo, git) para una lib común (o varias common- libs para diferentes temas) y publicar sus artefactos a través de un repositorio de artefactos (p. ej., maven / gems / pypi privados). Luego, en el microservicio agrega dependencia a las librerías necesarias. Por lo tanto, la reutilización de código es sencilla. En algunos casos, los sistemas de embalaje agregan algo de fricción (maven para uno) por lo que uno podría preferir usar un solo repo de git para todo y una configuración de proyecto de varios módulos. Eso no es tan limpio como el primer enfoque, pero funciona igual de bien y no está mal. Otras opciones son usar el submódulo de git (menos deseado) o el subárbol de git (mejor) para incluir el código fuente en un único repositorio "principal".
En cuanto al esquema, si quieres jugar según el libro, cada microservicio tiene su propia base de datos. No tocan los datos de los demás. Este es un enfoque muy modular que al principio parece agregar algo de fricción a su proceso, pero eventualmente creo que me lo agradecerá. Permitirá una iteración rápida en sus microservicios, por ejemplo, es posible que desee reemplazar una implementación de base de datos con otra implementación de base de datos para un servicio específico. ¡Imagínese hacer esto cuando todos sus servicios usan la misma base de datos! Buena suerte con eso ... Pero si cada servicio utiliza su propia base de datos, el servicio abstrae la base de datos correctamente (por ejemplo, no acepta consultas SQL como llamadas a la API ;-)) y luego cambiar de sitio a Cassandra de repente se vuelve factible. Hay otras ventajas de tener bases de datos completamente aisladas, por ejemplo, carga y escalado, encontrar cuellos de botella, administración, etc.
En resumen, un código común (utilidades, constantes, etc.): utilice un sistema de empaquetado o algún enlace de código fuente como git-tree
Base de datos: no tocas la mía, no toco la tuya. Esa es la mejor manera de evitar esto.
HTH, Ran.
El enfoque "más puro", es decir, el que le proporciona la menor cantidad de acoplamiento, es no compartir ningún código .
Si encuentra que dos servicios (llámelos A y B) necesitan la misma funcionalidad, sus opciones son:
- dividir si está desactivado como un servicio separado C, por lo que A y B pueden usar C
- muerde la bala y duplica el código
Si bien esto puede sonar incómodo, se evita el problema (no poco común) de crear una biblioteca "de utilidad" o "común" o de "infraestructura" de la que todos dependan, y que luego es realmente difícil de actualizar y cambiar (es decir, que servicios).
En la práctica, como de costumbre, es una compensación.
- Si la funcionalidad compartida es sustancial, buscaría un servicio separado.
- Si solo son constantes, una biblioteca compartida podría ser la mejor solución. Sin embargo, debes tener mucho cuidado con la compatibilidad con versiones anteriores.
- Para los datos de configuración, también podría implementar un servicio específico, posiblemente utilizando alguna tecnología existente como LDAP.
- Finalmente, para un código simple que probablemente evolucione de manera independiente, solo la duplicación podría ser la mejor solución.
Sin embargo, lo mejor dependerá de su situación y problema específicos.
En cuanto al principio ISP (principio de aislamiento de interfaz), los clientes deberían depender de la interfaz, no de las implementaciones. Sugeriría que si es posible compartir interfaces, no implementaciones, de esta forma sería mejor desvincular el sistema de la implementación.
De mi experiencia en proyectos
Comparta un WSDL cuando use SOAP (no el código del modelo de servicio, ya que deben generarse a partir del WSDL). Cuando use REST, tenga distintos modelos (copie sí pero no comparta) para el cliente y el servidor. Tan pronto como el segundo o tercer consumidor entren en juego, te meterás en problemas. Manténlos desacoplados. El funcionamiento y el uso de un servicio cambiaron en mi pasado con más frecuencia que las estructuras de datos. Otro cliente desea usar su servicio o una segunda versión debe ser operada al mismo tiempo.
Algunos pensamientos adicionales
Compartir es parcialmente contradictorio con la escalabilidad. Compartir-nada y compartir-algunos / compartir-todos tienen ventajas y desventajas. Compartir nada le brinda total flexibilidad en cualquier momento. Los microservicios son componentes independientes que proporcionan servicios de dominio particulares.
Compartir modelos de datos de dominio empresarial es un patrón común ( http://www.ivarjacobson.com/resources/resources/books/#object%20oriented%20software ) que evita las duplicaciones de los mismos. Dado que los microservicios dividen y conquistan las partes comerciales, puede ser difícil compartir algo del modelo de datos de dominio empresarial.
Los microservicios se comunican entre sí, así que entiendo la necesidad de compartir estos modelos de datos de comunicación (principalmente basados en HTTP). Compartir estos modelos de datos podría estar bien en caso de que tenga un mapeo uno a uno entre el proveedor del servicio y el consumidor. Tan pronto como tenga múltiples consumidores para un servicio que necesite diferentes modelos / campos dentro del modelo, se vuelve difícil.