Situación actual
Estamos implementando (y ahora manteniendo) una aplicación web de compras en línea en una arquitectura de microservicio.
Uno de los requisitos es que la empresa debe poder aplicar reglas sobre lo que nuestros clientes agregan a su carrito, a fin de personalizar su experiencia y el pedido final. Obviamente, se tuvo que establecer un motor de reglas de negocio e implementamos un "microservicio" específico para esto (si aún pudiéramos llamarlo así).
A lo largo de un año, este motor de reglas se ha vuelto cada vez más complejo, requiriendo más y más datos (por ejemplo, contenido del carrito pero también información del usuario, su función, sus servicios existentes, cierta información de facturación, etc.) para poder calcular esas reglas
Por el momento, nuestro shopping-cart
microservicio está recopilando todos estos datos de otros microservicios. Aunque parte de esta información es utilizada por shopping-cart
, la mayoría de las veces se usa principalmente para alimentar el motor de reglas.
Nuevos requisitos
Ahora llega la necesidad de otras aplicaciones / microservicios para reutilizar el motor de reglas para requisitos similares. En la situación actual, tendrían que transmitir el mismo tipo de datos, llamar a los mismos microservicios y construir (casi) los mismos recursos para poder llamar al motor de reglas.
Continuando como está, enfrentaremos varios problemas:
- todos (llamando al motor de reglas) tienen que reimplementar la obtención de datos, incluso si no los necesitan para sí mismos;
- las solicitudes al motor de reglas son complejas;
- continuando en esta dirección, tendremos que transportar estos datos por toda la red para muchas solicitudes (piense en μs A llamando a μs B llamando al motor de reglas, pero A ya tiene algunos de los datos que necesita el motor de reglas);
shopping-cart
se ha vuelto enorme debido a la obtención de todos los datos;- Probablemente olvide muchos ...
¿Qué podemos hacer para evitar estos problemas?
Idealmente, evitaríamos agregar más complejidad al motor de reglas. También debemos asegurarnos de que no se convierta en un cuello de botella; por ejemplo, algunos datos son bastante lentos para recuperar (10 segundos o incluso más), por lo que implementamos la recuperación previa de shopping-cart
manera que es más probable que los datos estén allí antes de llamar a las reglas motor y mantener una experiencia de usuario aceptable.
Algunas ideas
- Deje que el motor de reglas obtenga los datos que necesita. Esto agregaría aún más complejidad, violando el principio de responsabilidad única ( aún más ... );
- Implemente un proxy μs antes del motor de reglas para obtener los datos;
- Implemente un "captador de datos" μs que el motor de reglas llama para obtener todos los datos que necesita a la vez (consulta compuesta).
shopping-cart
, pero podríamos adaptarla fácilmente a las necesidades de los otros microservicios (todavía están relacionados con los usuarios, los productos y los pedidos). Tal como lo vemos, que se necesitan los mismos datos de entrada, sobre todo porque el negocio es capaz de elegir los predicados de aplicar. Todos los datos son proporcionados por otros microservicios, excepto el contenido del carrito. Obtener los datos no es complejo per se, pero se vuelve complejo cuando tiene que llamar a ~ 10 otros microservicios y mantener la estructura esperada por el motor de reglas.Respuestas:
Retrocedamos un segundo y evaluemos nuestro punto de partida antes de escribir esta respuesta que probablemente sea novedosa. Tienes:
Ok, esto no es tan bueno para microservicios. Un problema evidente es que ustedes parecen estar malinterpretando qué son los microservicios.
Debe definir algún tipo de API o método de comunicación que utilicen sus microservicios y que sea común. Esta podría ser una biblioteca que todos ellos pueden importar. Podría estar definiendo un protocolo de mensaje. Podría estar utilizando una herramienta existente ( busque buses de mensajes de microservicio como un buen punto de partida).
La cuestión de la comunicación entre servicios no es un problema "resuelto" per se, pero tampoco es un problema de "rodar su propio" en este momento. Muchas herramientas y estrategias existentes pueden hacer que su vida sea mucho más fácil.
Independientemente de lo que haga, elija un solo sistema e intente adaptar sus API de comunicación para usarlo. Sin una forma definida para que sus servicios interactúen, tendrá todas las desventajas de los microservicios y los servicios monolíticos y ninguna de las ventajas de ninguno.
La mayoría de sus problemas se derivan de esto.
Hazlos menos complejos.
Encuentre maneras de hacerlos menos complejos. Seriamente. Modelos de datos comunes, divida su motor de reglas individuales en otros más pequeños, o algo así. Haga que su motor de reglas funcione mejor. No tome el enfoque de "atascar todo en la consulta y siga haciéndolos complicados": considere seriamente lo que está haciendo y por qué.
Defina algún tipo de protocolo para sus datos. Mi conjetura es que ustedes no se han definido plan de API (según lo anterior) y han comenzado a escribir RESTO llama ad hoc cuando sea necesario. Esto se vuelve cada vez más complejo ya que ahora tiene que mantener cada microservicio cada vez que se actualiza algo.
Mejor aún, no eres exactamente la primera compañía en implementar una herramienta de compra en línea. Ve a buscar otras compañías.
Ahora que...
Después de esto, al menos probó algunos de los problemas más importantes.
El siguiente problema es esta pregunta de su motor de reglas. Espero que esto sea razonablemente apátrida, de modo que pueda escalarlo. Si es así, si bien no es óptimo, al menos no morirás en un resplandor de gloria o crearás soluciones alternativas.
Desea que su motor de reglas no tenga estado. Hágalo de manera que solo procese datos. Si lo encuentra como un cuello de botella, hágalo para que pueda ejecutar varios detrás de un proxy / equilibrador de carga. No es ideal, pero sigue siendo viable.
Dedique algo de tiempo a considerar si alguno de sus microservicios realmente debería incluirse en su motor de reglas. Si está aumentando la sobrecarga de su sistema de manera tan significativa solo para lograr una "arquitectura de microservicios", necesita pasar más tiempo planeando esto.
Alternativamente, ¿puede dividirse su motor de reglas en pedazos? Puede obtener ganancias simplemente haciendo que partes de sus reglas generen servicios específicos.
Suponiendo que este problema existe después de resolver los problemas anteriores, debe investigar seriamente por qué sucede esto. Se está desarrollando una pesadilla, pero en lugar de averiguar por qué (¿10 segundos? ¿Para enviar datos del portal de compras ? Llámame cínico, pero esto parece un poco absurdo) parece que estás reparando los síntomas en lugar de mirar el problema que causa los síntomas en El primer lugar.
Has utilizado la frase "recuperación de datos" una y otra vez. ¿Están estos datos en una base de datos? De lo contrario, considere hacer esto: si pasa tanto tiempo "manualmente" buscando datos, parece que usar una base de datos real sería una buena idea.
Es posible que pueda tener un diseño con una base de datos para los datos que obtiene (dependiendo de lo que sea, lo ha mencionado muchas veces), algunos motores de reglas y sus clientes.
Una última nota es que desea asegurarse de utilizar el control de versiones adecuado de sus API y servicios. Una versión menor no debe romper la compatibilidad con versiones anteriores. Si te encuentras liberando todos tus servicios al mismo tiempo para que funcionen, no tienes una arquitectura de microservicio, tienes una arquitectura monolítica distribuida.
Y, en última instancia, los microservicios no son una solución única para todos. Por el bien de todo lo que es sagrado, no lo hagas solo porque es lo nuevo de la moda.
fuente
Con la cantidad de información presentada sobre el motor de reglas y sus entradas y salidas, creo que su sugerencia no. 2 está en el camino correcto.
Los consumidores actuales del motor de reglas podrían externalizar el proceso de recopilación de la información requerida a un componente de propósito más especial.
Ejemplo: Actualmente está utilizando el motor de reglas para calcular los descuentos que deben aplicarse al contenido del carrito de compras. Las compras anteriores, la geografía y las ofertas actuales tienen en cuenta.
El nuevo requisito es utilizar gran parte de esta misma información para enviar por correo electrónico ofertas a clientes anteriores en función de las próximas ofertas especiales y compras anteriores. Las compras anteriores, las ofertas actuales y futuras tienen en cuenta.
Tendría dos servicios separados para esto. Cada uno confiaría en el servicio del motor de reglas para algunos de sus trabajos pesados. Cada uno de ellos recopilaría los datos necesarios necesarios para su solicitud al motor de reglas.
El motor de reglas solo aplica las reglas, los consumidores no necesitan preocuparse por los datos exactos que necesita el motor de reglas para el contexto particular, y estos nuevos servicios intermediarios solo hacen una cosa: reunir el contexto y pasar la solicitud al motor de reglas y devuelve la respuesta sin modificar.
fuente
La agregación de los datos necesarios para la decisión debe hacerse fuera del motor de reglas. Esto se debe a que están mejor diseñados como servicios apátridas como sea posible. La obtención de datos implica necesariamente el procesamiento asincrónico y la retención del estado. No importa mucho si la búsqueda se realiza mediante un proxy al frente del servicio de decisiones, las personas que llaman o un proceso de negocios.
Como cuestión práctica para la implementación, mencionaré que IBM Operational Decision Manager está comenzando a documentar y ya admite el uso del producto dentro de los contenedores de acopladores . Estoy seguro de que otros productos también brindan este soporte y que se convertirá en la corriente principal.
fuente
Supongo que, en mi pensamiento simple, ayudará a buscar previamente todos los datos necesarios haciendo un conjunto de llamadas asíncronas a los servicios de recuperación de datos tan pronto como el cliente comience a comprar y almacenar en caché los datos. Entonces, cuando tiene que llamar al servicio de reglas, los datos ya están allí. Y continúe estando disponible para otros servicios también durante la sesión.
fuente