2011-04-13 32 views
6

Estoy intentando usar CQRS y EventSorcing en mi nuevo proyecto. Estoy siguiendo el camino sugerido por Greg Young hace varios años (implementación de Mark Nijhof - http://cre8ivethought.com/blog/2009/11/12/cqrs--la-greg-young/). Y tengo algunos problemas relacionados con la escalabilidad de esta solución.Escalabilidad de CQRS + EventSourcing

Algunos puntos se mencionaron en el artículo this de Mark Nijhof. Pero el problema ahora es la parte Denormalizer, que es responsable de actualizar la base de datos de informes. Esta parte quiero que sea asincrónica, así que después de publicar eventos en el bus, quiero devolver el control inmediatamente. Sugerimos que Denormalizer podría implementarse como un servicio web independiente (WCF) que procesará los eventos entrantes y actualizará la base de datos del informe de forma sincronizada con lotes de comandos. Parece que podría ser un cuello de botella, por lo que también queremos agregar algo de escalabilidad en este momento: una solución de clúster. Pero en el caso del clúster no podemos controlar la secuencia de informes de las actualizaciones de la base de datos (o deberíamos implementar alguna lógica extraña y supongo que con errores que verificará las versiones de los objetos en el informe DB). Otro problema es la sostenibilidad de la solución: en caso de falla, perderemos las actualizaciones en el desnormalizador, en la medida en que no las conservemos en ninguna parte). Así que ahora estoy buscando solución a este problema (escalabilidad de Denormalizer) ¡cualquier pensamiento es bienvenido!

Respuesta

4

Para comenzar, definitivamente querrá tener el denormalizador alojado en un proceso separado. Desde allí, puede hacer que el dominio publique en su infraestructura de mensajería los eventos que ocurren en el dominio. Una estrategia fácil para ayudar a acelerar la desnormalización es dividir las cosas por tipo de mensaje/evento. En otras palabras, podría crear una cola separada para cada tipo de mensaje y luego hacer que el denormalizador se suscriba (utilizando un bus de mensajes) a los eventos correspondientes. La ventaja de esto es que no tiene mensajes apilados uno detrás del otro: todo comienza a ejecutarse en paralelo. Los únicos lugares en los que podría tener alguna disputa son las tablas que escuchan múltiples tipos. Aun así, ahora distribuyó la carga entre muchos puntos finales.

Siempre que use algún tipo de infraestructura de mensajería, no perderá los mensajes de evento cuando intenta desnormalizar. En cambio, después de un cierto número de intentos de falla, el mensaje se considerará "veneno" y se trasladará a una cola de errores. Simplemente monitoree la cola de errores para ver si hay problemas. Una vez que un mensaje se encuentra en la cola de errores, puede verificar sus registros para ver por qué está allí, solucionar el problema y luego volver a moverlo.

Otra consideración es que el ejemplo de Mark Nijhof es algo antiguo. Hay una serie de marcos CQRS disponibles, así como montones de consejos en el DDD/CQRS Google Group.

+0

¿Sería posible tener una cola separada para cada modelo de vista en lugar de por evento? –

+0

Absolutamente. La infraestructura del bus (como NServiceBus) se suscribiría a los eventos apropiados y le diría al editor que quiere una copia de los mensajes que se aplican al modelo de vista particular. –

+0

Gracias por su respuesta Jonathan. Bueno, también pensé en algún tipo de estrategia de separación de eventos para denormalizer con varias colas en hilos separados, por ejemplo. Supongo que la única regla aquí es mantener la secuencia de eventos para cada raíz de agregado particular. Pero el problema aquí es que no sé cómo usar un clúster en ese caso o incluso es posible usarlo, porque el clúster puede romper la secuencia de eventos. – Voice