Expérience réelle avec le cadre Axon
dans le cadre de la recherche de CQRS pour une utilisation avec un projet, j'ai couru à travers le Axone Cadre, et je me demandais si quelqu'un avait une vraie expérience de la vie avec elle. Juste pour être clair, je pose des questions sur le cadre, pas CQRS comme un modèle architectural.
mon projet utilise déjà des intégrations de ressorts et de ressorts qui correspondent parfaitement aux exigences D'Axon, mais avant que je n'y consacre beaucoup de temps, je voudrais savoir si quelqu'un a une expérience de première main. Dans en particulier, je suis intéressé je possibles pièges qui ne sont pas immédiatement apparents à partir de la documentation.
6 réponses
le framework s'appuie fortement sur l'externalisation d'événements, ce qui signifie que tous les changements d'état sont >écrits à la mémoire de données en tant qu'événements. "
C'est complètement faux, il ne s'appuient fortement sur l'événement d'approvisionnement. Une des implémentations pour stocker l'agrégat dans ce cadre utilise Event-Sourcing mais vous pouvez aussi facilement utiliser les classes fournies pour utiliser un modèle relationnel standard.
c'est juste mieux avec event-sourcing.
Si vous avez une référence historique de toutes vos données. C'est bien, mais cela rend la modification de votre >domaine après que vous êtes parti en production une proposition très intimidante, surtout si vous avez vendu >le client sur la "vérifiabilité forte" du système "
Je ne pense pas que ce soit beaucoup plus facile avec un modèle relationnel standard qui stocke seulement l'état actuel.
Le cadre encourage la dénormalisation de vos données, au point que certains l'ont suggéré >avoir un tableau par vue dans la demande. Cela rend votre application extrêmement >difficile à maintenir, surtout quand les développeurs originaux sont partis"
ceci n'est pas lié au cadre mais au modèle architectural utilisé (CQRS). Et désolé de mentionner que, mais avoir un dénormaliseur/vue est une bonne idée car il reste un objet simple.
donc la maintenance est facile parce que la requête/insertion SQL est aussi facile. Cet argument n'est donc pas très convaincant. Comment sur une vue qui utilise un modèle de 1000 tables avec des jointures intérieures partout et des requêtes SQL complexes?
encore une fois, CQRS aide parce que, fondamentalement, les données de vue est juste un SELECT * de la table qui correspondent à la vue.
si d'une façon ou d'une autre vous avez fait une erreur dans l'un des eventhandlers, votre seule option est de >"rejouer" l'eventlog, qui selon la taille de vos données peut prendre un très long >temps. L'outillage pour cela cependant est inexistant.
je 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 relire uniquement une partie de l'événement et non pas tout le contenu de l'événement store.
rejouer peut avoir des effets secondaires, donc > les développeurs ont peur de le faire
la rediffusion a des effets secondaires -> c'est faux. Pour moi, effets secondaires signifie modifier l'état du système. Dans un événement d'origine CQRS application, l'état est stocké dans l'event-store. Rejouer les é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 parce que vous êtes toujours en mesure de la corriger et rejouer l'événement une fois de plus.
il est extrêmement facile d'avoir des développeurs qui font des erreurs en utilisant ce framework. s'ils ne stockent pas >les changements aux objets de domaine dans les événements, la prochaine fois que vous rejouez vos événements Vous êtes dans un >surprise.
Eh bien si vous avez mal compris l'architecture, le concept, etc. alors ok je suis d'accord avec vous. Mais le problème n'est peut-être pas le cadre.
devez-vous stocker delta ? valeurs absolues ? si vous ne gardez pas un oeil sur vos développeurs >vous finirez forcément avec les deux et vous serez f***ed
je peux dire que pour chaque système, je dirais qu'il n'est pas directement lié au cadre lui-même. C'est comme dire, " Java est nul parce que vous pouvez tout foirer si quelqu'un code une mauvaise implémentation du hashCode et égale les méthodes."
et pour la dernière partie de votre commentaire, j'ai déjà vu des échantillons comme helloWorld avec le cadre de printemps. Bien sûr, il est complètement inutile dans un exemple simple.
soyez prudent dans votre commentaire pour faire une différence entre le concept (CQRS + EventSourcing) et le cadre. Faire une différence s'il vous plaît.
puisque vous avez déclaré vouloir utiliser CQRS pour votre projet (et je suppose que JVM est votre plateforme cible) je pense que Axon Framework est un excellent choix.
j'ai construit une plate-forme de trading assez complexe (non, l'échantillon de trading n'est pas complexe) et je n'ai pas vu de défauts évidents du cadre.
depuis que j'utilise L'Evensourcing, les fixtures de test ont rendu très facile d'écrire des tests de style BDD "donné, quand, puis". Cela vous permet de traiter un agrégat comme une boîte noire et de se concentrer sur la vérification de la bonne série d'événements lorsque vous le mettez dans une certaine commande.
A propos des pièges: avant de sauter dans, assurez-vous
- que vous avez compris les concepts de CQRS.
- faites une liste (papier, tableau blanc, n'importe quoi) de tous vos agrégats, gestionnaires de commandes, gestionnaires d'événements, sagas, commandes et événements. C'est la partie difficile de construire votre système, de comprendre ce qu'il devrait faire et comment. Après cette, le manuel de référence devrait vous montrer comment le raccorder avec Axon.
Certains non Axone des points précis:
être capable de reconstruire la vue store à partir d'événements est un concept D'EventSourcing, et pas quelque chose qui est exclusif à Axon, mais j'ai trouvé assez facile de créer un service qui va m'envoyer tous les événements à partir d'un type d'agrégat, agrégat id ou un certain type d'événement.
être en mesure de construire une nouvelle composante de rapport un an après la le projet est lancé et obtenir instantanément des rapports sur les données à partir du moment du lancement du projet et est génial.
J'utilise Axonfram Framework 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 libération étaient limités.
J'ai choisi Axonfram Framework parce que, au moment du coup d'envoi 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 année 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 difficile à devenir une opportunité de formation pour moi et les autres membres de l'équipe.
nous avons commencé à développer avec la version 1.0 D'Axonfram Framework et nous sommes passés à la version 1.4 au fur et à mesure que de nouvelles versions étaient publiées.
notre expérience d'équipe avec CQRS et la mise en œuvre fournie par le cadre AXA a été tout à fait positif.
il nous a fourni une manière cohérente et uniforme de développer chaque caractéristique qui nous a guidé et vous faire sentir à l'aise.
sans elle, certaines caractéristiques de l'application auraient été beaucoup plus compliquées à développer. Je me réfère principalement aux différents processus de longue date qui doivent être traités et à la logique de rémunération qui s'y rattache, mais aussi aux nombreux éléments logiques d'entreprise qui ont été nécessaires, ici et là, qui ont convenu joliment découplé dans l'architecture événementielle promue par le CQRS.
notre choix a été d'être conservateur dans le modèle write, donc nous avons préféré une persistance basée sur JPA au lieu de celle provenant de l'événement.
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 lorsque nécessaire.
quoi qu'il en soit nous avons développé le modèle d'écriture pendant que nous appliquions l'événement approvisionnement, donc nous prenons soin 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) à une toute nouvelle instance - le côté négatif dans ce cas ont été les événements upcasting (mais cette fonctionnalité a été grandement améliorée dans la version 2.0 imminente).
comme dans chaque projet pendant le développement nous avons trouvé beaucoup de bugs, dans notre code principalement, mais aussi dans les composants censés être matures et stables, comme le serveur d'application, le conteneur CIO, le cache, le moteur de flux de travail et certaines des autres bibliothèques qui se trouvent facilement dans toute application J2EE de grande taille.
comme N'importe quel autre produit humain Axonfram Framework N'était pas immunisé contre les bogues aussi, mais étonnamment pour un projet jeune et de niche comme celui-ci, ils ont été peu nombreux, pas critique, et rapidement résolu par de nouvelles versions.
Le genre et immédiate le soutien 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é mise en production il y a un an et est actuellement maintenue et en développement actif de nouvelles fonctionnalités.
Le client est satisfait et en redemande.
quand utiliser Axonfram Framework est plus une question de 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.
L'OP pose spécifiquement des questions sur les pièges relatifs au Cadre Axon plutôt que sur les CQR. Cela rend la question difficile à répondre, car Axon a commencé comme une mise en œuvre assez fidèle du célèbre livre de Eric Evans
le principal avantage est qu'il fait exactement ce qu'il dit sur l'étain: il gère les parties dures d'un design basé sur CQRS pour vous: agrégats, sagas, Event sourcing, handlers de commande, event handlers, cohérence de BASE etc. Lorsque vous suivez les meilleures pratiques, vous vous retrouvez avec une application hautement réactive et évolutive horizontalement. Si vous l'utilisez avec event sourcing, vos données sont totalement vérifiable, et au moins en théorie, vous pouvez déterminer l'état de votre demande avait à un moment donné dans le temps. Il n'y a pas d'outillage pour le faire; vous devrez rouler le vôtre.
le développeur principal du framework est très accessible et extrêmement bien informé sur le sujet de la haute performance et de l'informatique évolutive en Java. Il a tendance à répondre à toutes les questions de la liste de diffusion en quelques heures. Il s'agit à la fois d'un avantage et d'un piège majeur: à cette époque (début 2014), le cadre Axon dépend fortement d'une seule personne. Le reste des écueils que je voudrais mentionner sont probablement plus le résultat de l'approvisionnement d'événement que de CQRS ou Axon.
concevoir votre modèle de données très soigneusement à l'avance. Bien qu'il soit facile à ajouter, faire des changements fondamentaux à votre datamodel peut être très difficile. Si vous faites une erreur fondamentale dans le modèle de données, votre demande ne peut pas bien fonctionner, ou même 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 au sommet, cet agrégat peut devenir très grand car il s'accumule de plus en plus d'événements au fil du temps, et il peut prendre beaucoup de temps à charger et à stocker. Je ne sais pas ce qui se passera si ça continue jusqu'à ce qu'une instance de l'agrégat ne rentre plus dans RAM, mais j'imagine que ça pourrait être mauvais. Ne pas le faire de cette façon.
un autre écueil (lié au sourcing d'événements) est que, 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, comme vous devez parfois garder à l'esprit non seulement ce que le code fait aujourd'hui, mais aussi ce qu'il a fait dans le passé. Cela fait certainement rejouer (une partie de) le magasin d'événement pour reconstruire une table de vue une tâche non triviale.
corriger les erreurs de données peut être plus difficile qu'avec un design 'traditionnel'. Plutôt que d'un simple déclaration SQL, vous aurez souvent besoin de faire une commande pour changer 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 pour l'agrégat être rejoués. Si votre bug a causé des événements indésirables à appliquer, il peut me causer 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.
je suis actuellement avec une équipe qui travaille sur une plateforme de casino en ligne pour lancer notre marque Casumo cet été. Le domaine et la plate-forme sont construits en utilisant le cadre Axon et jusqu'à présent il nous a servi solidement.
on a économisé beaucoup de temps en n'ayant pas à construire toute l'infrastructure nécessaire pour la gestion des commandes, le routage des événements, l'obtention d'événements, le snapshoting, etc. et les API sont vraiment agréables à utiliser. Le seul bug que nous avons trouvé dans le framework jusqu'à présent a été corrigé .. sortie 12 heures plus tard et Allard est toujours rapide de prendre des suggestions sur les nouvelles fonctionnalités et de discuter des moyens de tirer parti du Cadre pour répondre à vos besoins.
alors que le cadre lui-même est écrit assez décent, son utilisation dans un projet du monde réel a été rien de moins qu'un cauchemar et le choix de ce cadre imo a été un facteur important contribuant à l'échec de ce projet.
le framework s'appuie fortement sur l'externalisation d'événements, ce qui signifie que tous les changements d'état sont écrits dans la mémoire de données en tant qu'événements. Si vous avez une référence historique de toutes vos données. C'est sympa, mais cela fait changer votre domaine après que vous soyez parti en production une proposition très intimidante surtout si vous avez vendu le client sur la "forte vérifiabilité" du système
vous ne pouvez pas demander aux gars de l'ops de faire 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 un tableau par vue dans l'application. Cela rend votre application extrêmement difficile à maintenir, surtout quand les développeurs sont allés
si d'une certaine façon vous avez fait une erreur dans l'une de les eventhandlers, votre seule option est de "rejouer" l'eventlog, qui peut prendre beaucoup de temps en fonction de la taille de vos données. L'outillage pour cela cependant est inexistant. Rejouer peut avoir des effets secondaires, de sorte que les développeurs ont peur de le faire
il est extrêmement facile d'avoir des développeurs qui font des erreurs en utilisant ce framework. s'ils ne stockent pas les modifications aux objets du domaine dans les événements, la prochaine fois que vous rejouerez vos événements vous serez surpris. Tu devrais stocker delta ? valeurs absolues ? si vous ne gardez pas un oeil sur vos développeurs, vous finirez forcément avec les deux et vous serez f***ed
il n'y a pratiquement pas d'adoption de ce cadre, donc googler pour des réponses ne vous fera aucun bien
même si le framework ne supporte pas encore la distribution, il est écrit en pensant à lui et les api sont un casse-tête à cause de cela. Désactiver un événement est async par défaut et si vous voulez vérifier si une exception a été soulevée en exécutant la commande, dites un duplicate username exception, vous devez passer dans un écouteur à votre commandler qui est un futur, puis vous attendez que le résultat du futur arrive, gérer toutes les exceptions vérifiées, interceptedexception etc et puis vous pouvez saisir l'exception qui a été lancée du futur. Bien sûr exceptions une commande peut soulever n'est pas évident à partir de l'api. Défaire le but des exceptions vérifiées
découvrez quelques-unes des exemple d'applications. J'ai en quelque sorte vous avez besoin d'une unité d'écoute pour créer une application addressbook? Ma bonté...