java cqrs axon

java - Experiencia de la vida real con Axon Framework



cqrs (6)

Como parte de la investigación de CQRS para su uso con un proyecto, me encontré con el Framework Axon , y me preguntaba si alguien tiene alguna experiencia de vida real con él. Solo para ser claro, estoy preguntando sobre el marco, no sobre CQRS como un patrón arquitectónico.

Mi proyecto ya usa Spring and Spring Integration, que encaja muy bien con los requisitos de Axon, pero antes de dedicarle mucho tiempo, me gustaría saber si alguien tiene alguna experiencia de primera mano. En particular, me interesan las posibles dificultades que no se desprenden de la documentación.


El marco se basa en gran medida en la distribución de eventos, lo que significa que todos los cambios de estado se escriben en el almacén de datos como eventos. "

Esto es completamente falso, no se basa en gran medida en el origen del evento. Una de las implementaciones para almacenar el agregado en este marco utiliza Event-Sourcing, pero también puede usar fácilmente las clases proporcionadas para usar un modelo relacional estándar.

Es simplemente mejor con el evento de origen.

Entonces tiene una referencia histórica de todos sus datos. Esto es bueno, pero hace que cambiar tu dominio después de que hayas entrado en producción sea una proposición muy desalentadora, especialmente si vendiste al cliente en la "auditabilidad fuerte" del sistema "

No creo que sea mucho más fácil con un modelo relacional estándar que solo almacena el estado actual.

El marco alienta la desnormalización de sus datos, hasta el punto de que algunos han sugerido tener una tabla por vista en la aplicación. Esto hace que su aplicación sea extremadamente difícil de mantener, especialmente cuando los desarrolladores originales se han ido ".

Esto no está relacionado con el marco sino con el patrón arquitectónico en uso (CQRS). Y lamento mencionarlo, pero tener un denormalizador / vista es una buena idea ya que se mantiene como un simple objeto.

Así que el mantenimiento es fácil porque la solicitud / inserción de SQL también es fácil. Entonces este argumento no es muy fuerte. ¿Qué tal una vista que utiliza un modelo de 1000 tablas con combinaciones internas en todas partes y consultas SQL complejas?

Nuevamente, CQRS ayuda porque, básicamente, los datos de vista son solo un SELECCIONAR * de la tabla que corresponde a la vista.

Si de alguna manera cometió un error en uno de los manejadores de eventos, su única opción es "reproducir" el registro de eventos, que dependiendo del tamaño de sus datos puede tomar un tiempo muy largo. Sin embargo, las herramientas para esto no existen.

Estoy de acuerdo con el hecho de que actualmente hay una falta de herramientas para reproducir eventos y que esto puede llevar mucho tiempo. Sin embargo, teóricamente es posible reproducir solo una parte del evento y no todo el contenido de la tienda de eventos.

La repetición puede tener efectos secundarios, por lo tanto, los desarrolladores se asustan de hacerlo

El evento de repetición tiene efectos secundarios -> eso no es cierto. Para mí, los efectos secundarios significan modificar el estado del sistema. En una aplicación CQRS basada en eventos, el estado se almacena en la tienda de eventos. La reproducción de los eventos no modifica la tienda de eventos. Puede tener un efecto secundario en el lado de la consulta del modelo sí. Pero no le importa si ha cometido un error porque todavía puede corregirlo y volver a reproducir el evento una vez más.

es extremadamente fácil confundir a los desarrolladores con este marco. si no almacenan> cambios a objetos de dominio en eventos, la próxima vez que reproduzca sus eventos, se encontrará con una> sorpresa.

Bueno, si hiciste mal uso y malinterpretaste la arquitectura, el concepto, etc. entonces estoy de acuerdo, estoy de acuerdo contigo. Pero tal vez el problema no sea el marco aquí.

¿Deberías almacenar Delta''s? valores absolutos ? si no controlas a tus desarrolladores> estás obligado a terminar con ambos y serás f *** ed

Puedo decir que para cada sistema diría que no está directamente relacionado con el marco. Es como decir: "Java es una porquería porque puedes estropear todo si alguien codifica una mala implementación de hashCode e iguala los métodos".

Y para la última parte de su comentario, ya he visto muestras como helloWorld con el marco Spring. Por supuesto, es completamente inútil en un simple ejemplo.

Tenga cuidado en su comentario para hacer una diferencia entre el concepto (CQRS + EventSourcing) y el marco. Marca la diferencia por favor


Actualmente estoy trabajando con un equipo en una plataforma de casinos en línea que lanzará nuestra marca Casumo este verano. El dominio y la plataforma se construyen utilizando Axon Framework y hasta ahora nos ha servido sólidamente.

Se ha ahorrado mucho tiempo sin tener que construir toda la infraestructura necesaria para el manejo de comandos, el enrutamiento de eventos, el aprovisionamiento de eventos, la captura de instantáneas, etc., y es muy agradable trabajar con las API. El único error que encontramos en el marco hasta el momento se corrigió en ... la versión 12 horas después y Allard siempre se apresura a tomar sugerencias sobre las nuevas funciones y a debatir formas de aprovechar el marco para satisfacer sus necesidades.


Dado que ha declarado que desea utilizar CQRS para su proyecto (y supongo que la JVM es su plataforma de destino), creo que Axon Framework es una excelente opción.

He construido una plataforma de negociación bastante compleja (no, la muestra de trading no es compleja) y no he visto ningún defecto obvio del framework.

Como utilizo EventSourcing, los dispositivos de prueba hacen que sea muy fácil escribir pruebas de estilo BDD "dado, cuando, entonces". Esto le permite tratar un agregado como una caja negra y concentrarse en verificar que salga el conjunto correcto de eventos cuando ingresa un determinado comando.

Acerca de las trampas: antes de saltar, asegúrese

  1. Que tiene los conceptos de CQRS resueltos.
  2. Haga una lista (papel, pizarra, lo que sea) de todos sus agregados, manejadores de comandos, controladores de eventos, sagas, comandos y eventos. Esta es la parte más difícil de construir su sistema, averiguar qué debería hacer y cómo. Después de esto, el manual de referencia debería mostrarle cómo conectarlo todo junto con Axon.

Algunos puntos no específicos de Axon:

Poder reconstruir view store desde eventos es un concepto de EventSourcing, y no algo exclusivo de Axon, pero me resultó bastante fácil crear un servicio que me envíe todos los eventos desde un tipo agregado, ID agregado o un determinado tipo de evento.

Ser capaz de construir un nuevo componente de informes un año después de que se lanza el proyecto y obtener instantáneamente informes sobre los datos desde el momento del lanzamiento del proyecto y en adelante es increíble.


El OP pregunta específicamente sobre las trampas relacionadas con el Marco Axon en lugar de CQRS. Esto hace que la pregunta sea difícil de responder, ya que Axon comenzó como una implementación bastante fiel del famoso libro de Eric Evans.

La principal ventaja es que hace exactamente lo que dice en la lata: maneja las partes duras de un diseño basado en CQRS para usted: agregados, sagas, fuentes de eventos, controladores de comandos, controladores de eventos, coherencia BASE, etc. Cuando se sigue lo mejor prácticas, terminas con una aplicación altamente sensible y escalable horizontalmente. Si lo utiliza con fuentes de eventos, sus datos son completamente auditables y, al menos en teoría, puede determinar el estado de su aplicación en un momento dado. No se proporciona herramientas para hacer esto; Tendrás que hacer tu propio.

El desarrollador principal del framework es muy accesible y conocedor del tema de alto rendimiento y computación escalable en java. Tiende a responder cada pregunta en la lista de correo en pocas horas. Esto es a la vez una ventaja y el mayor escollo: en este momento (principios de 2014), el Marco Axon depende en gran medida de una persona. El resto de las trampas que me gustaría mencionar son probablemente más el resultado de la obtención de eventos que de CQRS o Axon.

Diseña tu modelo de datos con mucho cuidado por adelantado. Aunque es fácil de agregar, hacer cambios fundamentales en su modelo de datos puede ser muy difícil. Si cometes un error fundamental en el modelo de datos, es posible que tu aplicación no funcione bien o incluso que deje de funcionar. Por ejemplo, si elige un modelo de datos en forma de árbol, con una raíz agregada de larga vida en la parte superior, este agregado puede crecer mucho a medida que acumula más y más eventos a lo largo del tiempo y puede llevar mucho tiempo cargarlos y almacenarlos. No sé qué sucederá si esto continúa hasta que una instancia del agregado ya no cabe en la RAM, pero imagino que podría ser malo. No lo hagas de esa manera.

Otro inconveniente (relacionado con el evento) es que, después de varias revisiones, puede ser cada vez más difícil razonar sobre el estado de un agregado, ya que a veces hay que tener en cuenta no solo lo que hace el código hoy, sino también lo que lo hizo en el pasado. Esto definitivamente hace que reproducir (una parte de) el almacén de eventos para reconstruir una tabla de vista sea una tarea no trivial.

Reparar errores de datos puede ser más difícil que con un diseño ''tradicional''. En lugar de una simple instrucción SQL, a menudo necesitarás hacer un comando para cambiar el estado de tu aplicación. Si el error en sus datos fue causado por un controlador de eventos defectuoso, generalmente puede corregir el error, borrar las instantáneas y permitir que los eventos para el agregado se reproduzcan. Si su error provocó la aplicación de eventos espurios, me puede costar mucho más solucionarlo. Los eventos defectuosos permanecerán en la tienda de eventos, y es posible que deba aplicar algunos nuevos para restaurar sus datos al estado correcto o cambiar el código para ignorar o corregir su comportamiento.


He estado usando AxonFramework por más de un año en un proyecto complejo desarrollado para un gran banco.

Los requisitos eran exigentes, las expectativas de los clientes eran altas y los plazos de publicación eran reducidos.

Elegí AxonFramework porque, en el momento del lanzamiento del proyecto, era la implementación más completa y mejor documentada de CQRS disponible en Java, bien diseñada, fácil de integrar, probar y ampliar.
Después de más de un año, creo que estas consideraciones siguen siendo válidas y actuales.

Otra consideración ha guiado mi elección: quería que el compromiso en un proyecto tan difícil se convirtiera en una oportunidad de capacitación para mí y para otros miembros del equipo.

Comenzamos a desarrollar AxonFramework versión 1.0 y pasamos a la versión 1.4 a medida que se lanzaban versiones más nuevas.

Nuestra experiencia de equipo con CQRS y la implementación proporcionada por AxonFramework fue absolutamente positiva.

Nos proporcionó una manera consistente y uniforme para desarrollar cada función que nos guiaba y hacía que se sintiera a gusto.

Sin él, algunas características de la aplicación habrían sido mucho más complicadas de desarrollar. Me refiero principalmente a los diversos procesos de larga ejecución que deben ser manejados ya la lógica de compensación relacionada, pero también a las muchas piezas lógicas de negocios que han sido necesarias, aquí y allá, que encajaron bien y desacopladas en la arquitectura impulsada por eventos promovido por CQRS.

Nuestra elección fue ser conservadores en el modelo de escritura, por lo que preferimos una persistencia basada en JPA en lugar de la fuente del evento.

El modelo de consulta está compuesto de vistas. Hemos tratado de asegurarnos de que cada vista contenga todos los datos requeridos desde una sola página usando vistas intermedias cuando sea necesario.

De todos modos, desarrollamos el modelo de escritura cuando estábamos aplicando el abastecimiento de eventos, por lo que nos ocupamos de modificar el estado de los agregados exclusivamente a través de eventos. Cuando el cliente solicitó una función de clonación de un agregado muy complejo, fue solo una cuestión de reproducir los eventos de origen (con uuid traducido) a una instancia completamente nueva; el inconveniente en este caso fue la reubicación de eventos (pero esta funcionalidad era muy mejorado en la inminente versión 2.0).

Como en cada proyecto durante el desarrollo encontramos muchos errores, principalmente en nuestro código, pero también en componentes supuestamente maduros y estables, como el servidor de aplicaciones, el contenedor IoC, el caché, el motor de flujo de trabajo y algunos de los otros bibliotecas que se pueden encontrar fácilmente en cualquier aplicación J2EE grande.

Como cualquier otro producto humano, AxonFramework no era inmune a los errores, pero sorprendentemente para un proyecto joven y de nicho como este, han sido pocos, no críticos, y se resolvieron rápidamente con nuevos lanzamientos.

El apoyo amable e inmediato proporcionado por el autor en la lista de correo es otra característica invaluable y me ayudó mucho cuando estaba en problemas.

La aplicación fue lanzada en producción hace un año y actualmente se mantiene y en desarrollo activo de nuevas características.

El cliente está satisfecho y pide más.

Cuándo usar AxonFramework es más una cuestión de cuándo usar CQRS. Para obtener una respuesta, vale la pena volver a la documentación oficial: http://www.axonframework.org/docs/1.4/introduction.html#d4e51

En nuestro caso definitivamente valió la pena.


Si bien el marco en sí está escrito lo suficientemente decente, su uso en un proyecto del mundo real ha sido una pesadilla y la elección de este marco fue uno de los principales factores que contribuyeron a la falla de este proyecto.

El marco se basa en gran medida en el suministro de eventos, lo que significa que todos los cambios de estado se escriben en el almacén de datos como eventos. Entonces tiene una referencia histórica de todos sus datos. Esto es agradable, pero hace que cambiar de dominio una vez que haya entrado en producción sea una proposición muy desalentadora, especialmente si vendió al cliente en la "auditabilidad fuerte" del sistema.

No puede tener ops chicos hacer cambios ad-hoc a la base de datos

El marco fomenta la desnormalización de sus datos, hasta el punto de que algunos han sugerido tener una tabla por vista en la aplicación. Esto hace que tu aplicación sea extremadamente difícil de mantener, especialmente cuando los desarrolladores originales se han ido.

Si de alguna manera cometió un error en uno de los manejadores de eventos, su única opción es "reproducir" el registro de eventos, que dependiendo del tamaño de sus datos puede tomar mucho tiempo. Sin embargo, las herramientas para esto no existen. La repetición puede tener efectos secundarios, por lo que los desarrolladores tienen miedo de hacerlo

es extremadamente fácil confundir a los desarrolladores con este marco. si no almacenan cambios en objetos de dominio en eventos, la próxima vez que reproduzca sus eventos se sorprenderá. ¿Deberías almacenar Delta''s? valores absolutos ? si no controlas a tus desarrolladores, seguramente terminarás con ambos y serás f *** ed

Prácticamente no hay adopción de este marco, por lo que buscar en Google las respuestas no te hará ningún bien

A pesar de que el framework aún no admite la distribución, está escrito teniendo esto en cuenta y es difícil trabajar con las API por eso. Disparar un evento es asíncrono por defecto y si desea comprobar si se generó una excepción ejecutando el comando, digamos una excepción de nombre de usuario duplicada, necesita pasar un oyente a su manejador de comandos, que es un futuro, luego espera por el futuro resultado para entrar, manejar cualquier excepción marcada, interuptedexception, etc. y luego puede tomar la excepción que se lanzó desde el futuro. Por supuesto, las excepciones que un comando puede generar no son evidentes desde la API. Derrotando el propósito de las excepciones marcadas

Mira algunas de las aplicaciones de ejemplo . ¿De alguna manera necesito un oyente de unidad de trabajo para crear una aplicación de libreta de direcciones? Dios mío...