web-dev-qa-db-fra.com

Expérience réelle avec Axon Framework

Dans le cadre de la recherche de CQRS pour une utilisation avec un projet, j'ai parcouru le Axon Framework , et je me demandais si quelqu'un avait une expérience de la vie réelle avec. Juste pour être clair, je pose des questions sur le cadre, pas sur le CQRS en tant que modèle architectural.

Mon projet utilise déjà Spring and Spring Integration qui correspond bien aux propres exigences d'Axon, mais avant d'y consacrer beaucoup de temps, je voudrais savoir si quelqu'un a une expérience de première main. En particulier, je suis intéressé par les pièges possibles qui ne sont pas immédiatement apparents dans la documentation.

45
mhvelplund

Le cadre repose largement sur l'externalisation d'événements, ce qui signifie que tous les changements d'état sont écrits dans le magasin de données en tant qu'événements. "

C'est complètement faux, cela ne dépend pas beaucoup de la recherche d'événements. L'une des implémentations pour stocker l'agrégat dans ce cadre utilise Event-Sourcing mais vous pouvez facilement utiliser également les classes fournies pour utiliser un modèle relationnel standard.

C'est juste mieux avec le sourcing d'événements.

Vous avez donc une référence historique de toutes vos données. C'est sympa mais cela rend le changement de votre> domaine après que vous soyez entré en production une proposition très intimidante surtout si vous avez vendu le client sur la "forte auditabilité" du système ""

Je ne pense pas que ce soit beaucoup plus facile avec un modèle relationnel standard qui ne stocke que l'état actuel.

Le cadre encourage la dénormalisation de vos données, au point que certains ont suggéré d'avoir une table par vue dans l'application. Cela rend votre application extrêmement difficile à maintenir, surtout lorsque les développeurs d'origine sont partis "

Ceci n'est pas lié au cadre mais au modèle architectural utilisé (CQRS). Et désolé de le mentionner, mais avoir un dénormaliseur/vue est une bonne idée car il reste un simple objet.

La maintenance est donc facile car la requête/insertion SQL est également facile. Cet argument n'est donc pas très fort. Que diriez-vous d'une vue qui utilise un modèle de 1000 tables avec des jointures internes partout et des requêtes SQL complexes?

Encore une fois, CQRS aide car, fondamentalement, les données de vue ne sont qu'un SELECT * de la table qui correspond à la vue.

si vous avez fait une erreur dans l'un des gestionnaires d'événements, votre seule option est de "rejouer" le journal des événements, ce qui, en fonction de la taille de vos données, peut prendre très longtemps. L'outillage pour cela est cependant inexistant.

Je suis d'accord sur le fait qu'il y a actuellement un manque d'outils pour rejouer les événements et que cela peut prendre beaucoup de temps. Cependant, il est théoriquement possible de ne rejouer qu'une partie de l'événement et non tout le contenu du magasin d'événements.

La relecture peut avoir des effets secondaires, donc> les développeurs ont peur de le faire

La relecture d'un événement a des effets secondaires -> c'est faux. Pour moi, les effets secondaires signifient modifier l'état du système. Dans une application CQRS provenant d'événements, l'état est stocké dans le magasin d'événements. La relecture des événements ne modifie pas le magasin d'événements. Vous pouvez avoir un effet secondaire sur le côté requête du modèle oui. Mais vous ne vous souciez pas si vous avez fait une erreur car vous pouvez toujours la corriger et rejouer l'événement une fois de plus.

il est extrêmement facile de faire gâcher les développeurs en utilisant ce framework. s'ils ne stockent pas> les modifications apportées aux objets de domaine dans les événements, la prochaine fois que vous rejouerez vos événements, vous serez surpris.

Eh bien, si vous avez mal utilisé et mal compris l'architecture, le concept, etc., alors d'accord, je suis d'accord avec vous. Mais peut-être que le problème n'est pas le cadre ici.

Devriez-vous stocker des delta? des valeurs absolues? si vous ne gardez pas un œil sur vos développeurs> vous êtes obligé de vous retrouver avec les deux et vous serez f *** ed

Je peux dire que pour chaque système, je dirais que ce n'est pas directement lié au cadre lui-même. C'est comme dire: "Java est de la merde parce que vous pouvez tout gâcher si quelqu'un code une mauvaise implémentation de hashCode et équivaut à des méthodes."

Et pour la dernière partie de votre commentaire, j'ai déjà vu des échantillons comme helloWorld avec le framework Spring. Bien sûr, cela est complètement inutile dans un exemple simple.

Soyez prudent dans votre commentaire pour faire la différence entre le concept (CQRS + EventSourcing) et le framework. Faites une différence s'il vous plaît.

33
FrenchSpidey

Puisque vous avez déclaré que vous souhaitez utiliser CQRS pour votre projet (et je suppose que la JVM est votre plate-forme cible), je pense qu'Axon Framework est un excellent choix.

J'ai construit une plate-forme de négociation assez complexe (non, l'échantillon de négociation n'est pas complexe) et je n'ai vu aucun défaut évident du cadre.

Depuis que j'utilise EventSourcing, les montages de test ont rendu très facile l'écriture de style BDD "donné, quand, puis" tests. Cela vous permet de traiter un agrégat comme une boîte noire et de vous concentrer sur la vérification que le bon ensemble d'événements sort lorsque vous entrez une certaine commande.

À propos des pièges: avant de sauter, assurez-vous

  1. Que vous avez compris les concepts du CQRS.
  2. Faites une liste (papier, tableau blanc, peu importe) de tous vos agrégats, gestionnaires de commandes, gestionnaires d'événements, sagas, commandes et événements. C'est la partie la plus difficile de la construction de votre système, savoir ce qu'il doit faire et comment. Après cela, le manuel de référence devrait vous montrer comment câbler le tout avec Axon.

Quelques points non spécifiques à Axon:

Être capable de reconstruire le magasin de vues à partir d'événements est un concept d'EventSourcing, et non quelque chose qui est exclusif à Axon, mais j'ai trouvé assez facile de créer un service qui m'enverra tous les événements à partir d'un type d'agrégat, d'un ID d'agrégat ou d'un certain type d'événement.

Être capable de créer un nouveau composant de rapport un an après le lancement du projet et d'obtenir instantanément des rapports sur les données à partir du lancement du projet et au-delà est génial.

21
Per Wiklander

J'utilise AxonFramework depuis plus d'un an sur un projet complexe développé pour une grande banque.

Les exigences étaient exigeantes, les attentes des clients étaient élevées et les délais de sortie étaient serrés.

J'ai choisi AxonFramework car, au moment du lancement du projet, c'était l'implémentation la plus complète et la mieux documentée de CQRS disponible en Java, bien conçue, facile à intégrer, à tester et à étendre.
Après plus d'un an, je pense que ces considérations sont toujours valables et actuelles.

Une autre considération a guidé mon choix: je voulais que l'engagement sur un projet aussi difficile devienne une opportunité de formation pour moi et les autres membres de l'équipe.

Nous avons commencé à développer avec AxonFramework version 1.0 et sommes passés à la version 1.4 à mesure que de nouvelles versions étaient publiées.

Notre expérience d'équipe avec CQRS et l'implémentation fournie par AxonFramework a été absolument positive.

Cela nous a fourni une manière cohérente et uniforme pour développer chaque fonctionnalité qui nous a guidés et vous mettre à l'aise.

Sans cela, certaines fonctionnalités de l'application auraient été beaucoup plus compliquées à développer. Je me réfère principalement aux différents processus de longue haleine qui doivent être traités et à la logique de rémunération connexe, mais aussi aux nombreux éléments de logique métier qui ont été nécessaires, ici et là, qui s'intégraient bien et se découplaient dans l'architecture événementielle. promu par le CQRS.

Notre choix était d'être prudent dans le modèle d'écriture, nous avons donc préféré une persistance basée sur JPA plutôt que celle d'origine.

Le modèle de requête est composé de vues. Nous avons essayé de nous assurer que chaque vue contient toutes les données requises à partir d'une seule page en utilisant des vues intermédiaires si nécessaire.

Quoi qu'il en soit, nous avons développé le modèle d'écriture lorsque nous appliquions le sourcing d'événements, nous nous occupons donc de modifier l'état des agrégats exclusivement par le biais d'événements. Lorsque le client a demandé une fonction de clonage d'un agrégat très complexe, il s'agissait simplement de rejouer les événements source (avec uuid traduit) vers une toute nouvelle instance - l'inconvénient dans ce cas a été la retransmission des événements (mais cette fonctionnalité était considérablement amélioré dans la version imminente 2.0).

Comme dans chaque projet au cours du développement, nous avons trouvé beaucoup de bogues, principalement dans notre code, mais aussi dans des composants censés être matures et stables, comme le serveur d'applications, le conteneur IoC, le cache, le moteur de workflow et certains autres bibliothèques qui se trouvent facilement dans n'importe quelle grande application J2EE.

Comme tout autre produit humain AxonFramework n'était pas à l'abri des bugs aussi, mais étonnamment pour un projet jeune et de niche comme celui-ci, ils ont été peu nombreux, non critiques et rapidement résolus par de nouvelles versions.

Le soutien aimable et immédiat fourni par l'auteur sur la liste de diffusion est une autre caractéristique inestimable et m'a beaucoup aidé lorsque j'étais en difficulté.

L'application a été lancée en production il y a un an et est actuellement maintenue et en cours de développement actif de nouvelles fonctionnalités.

Le client est satisfait et en redemande.

Quand utiliser AxonFramework est plus une question de savoir quand utiliser CQRS. Pour une réponse, il vaut la peine de revenir à la documentation officielle: http://www.axonframework.org/docs/1.4/introduction.html#d4e51

Dans notre cas, cela en valait vraiment la peine.

15
dgiffone

Le PO pose spécifiquement des questions sur les pièges liés au cadre Axon plutôt qu'au CQRS. Cela rend la question difficile à répondre, car Axon a commencé comme une implémentation assez fidèle du célèbre livre par Eric Evans

Le principal avantage est qu'il fait exactement ce qu'il dit sur l'étain: il gère pour vous les parties dures d'une conception basée sur CQRS: agrégats, sagas, sourcing d'événements, gestionnaires de commandes, gestionnaires d'événements, cohérence BASE, etc. Lorsque vous suivez le meilleur pratiques, vous vous retrouvez avec une application très réactive et évolutive horizontalement. Si vous l'utilisez avec le sourcing d'événements, vos données sont entièrement auditables et, du moins en théorie, vous pouvez déterminer l'état de votre application à un moment donné. L'outillage pour ce faire n'est pas fourni; vous devrez rouler le vôtre.

Le développeur principal du framework est très accessible et extrêmement compétent en matière de calcul haute performance et évolutif en Java. Il a tendance à répondre à toutes les questions de la liste de diffusion en quelques heures. C'est à la fois un avantage et un écueil majeur: à l'heure actuelle (début 2014), le Framework Axon dépend fortement d'une seule personne. Les autres pièges que je voudrais mentionner sont probablement plus le résultat de la recherche d'événements que du CQRS ou d'Axon (à partir de 2018 le framework est supporté par la société Axoniq)

Concevez votre modèle de données très soigneusement dès le départ. Bien qu'il soit facile d'y ajouter, apporter des modifications fondamentales à votre modèle de données peut être très difficile. Si vous faites une erreur fondamentale dans le modèle de données, votre application peut ne pas fonctionner correctement, voire ne pas fonctionner du tout. Par exemple, si vous choisissez un modèle de données en forme d'arbre, avec une racine d'agrégat à longue durée de vie en haut, cet agrégat peut devenir très volumineux car il accumule de plus en plus d'événements au fil du temps, et le chargement et le stockage peuvent prendre du temps. Je ne sais pas ce qui se passera si cela continue jusqu'à ce qu'une instance de l'agrégat ne rentre plus dans la RAM, mais j'imagine que cela pourrait être mauvais. Ne le faites pas comme ça.

Un autre écueil (lié à la recherche d'événements) est qu'après un certain nombre de révisions, il peut devenir de plus en plus difficile de raisonner sur l'état d'un agrégat, car il faut parfois garder à l'esprit non seulement ce que fait le code aujourd'hui, mais aussi ce qu'il fait dans le passé. Cela fait définitivement rejouer (une partie de) le magasin d'événements pour reconstruire une table de vue une tâche non triviale.

La correction des erreurs de données peut être plus difficile qu'avec une conception "traditionnelle". Plutôt qu'une simple instruction SQL, vous devrez souvent exécuter une commande pour modifier l'état de votre application. Si l'erreur dans vos données a été causée par un gestionnaire d'événements défectueux, vous pouvez généralement simplement corriger le bogue, effacer les instantanés et laisser les événements de l'agrégat être relus. Si votre bogue a provoqué l'application d'événements parasites, cela peut me poser beaucoup plus de problèmes à corriger. Les événements défectueux resteront dans le magasin d'événements, et vous devrez peut-être en appliquer de nouveaux pour restaurer vos données à l'état correct, ou modifier le code pour ignorer ou corriger leur comportement.

8
Mzzl

Je suis actuellement avec une équipe travaillant sur une plateforme de casino en ligne qui lance notre marque Casumo cet été. Le domaine et la plate-forme sont construits à l'aide d'Axon Framework et jusqu'à présent, ils nous ont servi solidement.

Beaucoup de temps a été économisé sans avoir à construire toute l'infrastructure nécessaire pour la gestion des commandes, le routage des événements, le sourcing des événements, les instantanés, etc. et les API sont vraiment agréables à utiliser. Le seul bogue que nous avons trouvé jusqu'à présent dans le cadre a été corrigé dans .. version 12 heures plus tard et Allard est toujours rapide à prendre des suggestions sur de nouvelles fonctionnalités et à discuter des moyens de tirer parti du cadre pour répondre à vos besoins.

6

Bien que le cadre lui-même soit suffisamment décent, son utilisation dans un projet réel n'a été qu'un cauchemar et le choix de ce cadre imo a été un facteur majeur contribuant à l'échec de ce projet.

Le cadre repose largement sur l'externalisation d'événements, ce qui signifie que tous les changements d'état sont écrits dans le magasin de données en tant qu'événements. Vous avez donc une référence historique de toutes vos données. C'est bien, mais le changement de domaine après la mise en production est une proposition très intimidante, surtout si vous avez vendu le client sur la "forte auditabilité" du système.

Vous ne pouvez pas demander aux gars d'opérations d'apporter des modifications ad hoc à la base de données

Le cadre encourage la dénormalisation de vos données, au point que certains ont suggéré d'avoir une table par vue dans l'application. Cela rend votre application extrêmement difficile à maintenir, surtout lorsque les développeurs d'origine sont partis

si vous avez fait une erreur dans l'un des gestionnaires d'événements, votre seule option est de "rejouer" le journal des événements, ce qui, selon la taille de vos données, peut prendre très longtemps. L'outillage pour cela est cependant inexistant. La relecture peut avoir des effets secondaires, donc les développeurs ont peur de le faire

il est extrêmement facile de faire gâcher les développeurs en utilisant ce framework. s'ils ne stockent pas les modifications apportées aux objets de domaine dans les événements, la prochaine fois que vous rejouerez vos événements, vous serez surpris. Devriez-vous stocker des delta? des valeurs absolues? si vous ne gardez pas un œil sur vos développeurs, vous vous retrouverez avec les deux et vous serez f *** ed

Il n'y a pratiquement pas d'adoption de ce cadre, donc la recherche de réponses sur Google ne vous sera d'aucune utilité

Même si le cadre ne prend pas encore en charge la distribution, il est écrit en pensant à lui et les API sont difficiles à travailler à cause de cela. Le déclenchement d'un événement est asynchrone par défaut et si vous voulez vérifier si une exception a été déclenchée lors de l'exécution de la commande, par exemple une exception de nom d'utilisateur en double, vous devez passer un écouteur à votre gestionnaire de commandes qui est un futur, puis vous attendez le futur. résultat à venir, gérer toutes les exceptions vérifiées, les interruptions d'exception, etc., puis vous pouvez saisir l'exception qui a été levée du futur. Bien entendu les exceptions qu'une commande peut déclencher n'apparaissent pas dans l'API. Défaire le but des exceptions vérifiées

Découvrez quelques-unes des exemples d'applications . J'ai en quelque sorte besoin d'un écouteur d'unité de travail pour créer une application de carnet d'adresses? Mon Dieu...

5
Martin flower