Dans quelle mesure une commande doit-elle être granulaire dans un modèle CQ [R] S?

17

J'envisage un projet pour migrer une partie de notre SOA basé sur WCF vers un modèle de bus de service (probablement nServiceBus) et utiliser un pub-sub de base pour réaliser la séparation des requêtes de commandes .

Je ne suis pas nouveau dans SOA, ni même dans les modèles de bus de service, mais j'avoue que jusqu'à récemment, mon concept de "séparation" était limité à la mise en miroir et à la réplication de bases de données courantes. Pourtant, je suis attiré par l'idée car elle semble offrir tous les avantages d'un système finalement cohérent tout en évitant bon nombre des inconvénients évidents (notamment le manque de soutien transactionnel approprié).

J'ai beaucoup lu sur le sujet d'Udi Dahan qui est fondamentalement le gourou des architectures ESB (au moins dans le monde Microsoft), mais une chose qu'il dit me laisse vraiment perplexe:

Au fur et à mesure que nous obtenons de plus grandes entités avec plus de champs, nous avons également plus d'acteurs travaillant avec ces mêmes entités, et plus la probabilité que quelque chose touche certains attributs à un moment donné est élevée, ce qui augmente le nombre de conflits de concurrence.

[...]

Un élément central du CQRS est de repenser la conception de l'interface utilisateur pour nous permettre de saisir l'intention de nos utilisateurs de telle sorte que faire un client préféré est une unité de travail différente pour l'utilisateur que d'indiquer que le client a déménagé ou qu'il a obtenu marié. L'utilisation d'une interface utilisateur de type Excel pour les modifications de données ne capture pas l'intention, comme nous l'avons vu ci-dessus.

- Udi Dahan, CQRS clarifié

Du point de vue décrit dans la citation, il est difficile de contester cette logique. Mais cela semble aller à contre-courant en ce qui concerne les OSS. Une architecture SOA (et vraiment des services en général) est censée traiter les messages à granularité grossière afin de minimiser les conversations réseau - parmi de nombreux autres avantages.

Je me rends compte que le bavardage réseau est moins un problème lorsque vous avez des systèmes hautement distribués avec une bonne file d'attente de messages et aucun des bagages de RPC, mais il ne semble pas sage de rejeter complètement le problème. Udi semble presque dire que chaque changement d'attribut (c.-à-d. Mise à jour de champ) devrait être sa propre commande, ce qui est difficile à imaginer dans le contexte d'un utilisateur mettant potentiellement à jour des centaines ou des milliers d'entités et d'attributs combinés, comme c'est souvent le cas avec un outil traditionnel. service Web.

Une mise à jour par lots dans SQL Server peut prendre une fraction de seconde étant donné une bonne requête hautement paramétrée, un paramètre de valeur de table ou une insertion en bloc dans une table intermédiaire; le traitement de toutes ces mises à jour une à la fois est lent, lent, lent et le matériel de base de données OLTP est le plus cher de tous à évoluer / évoluer.

Existe-t-il un moyen de concilier ces préoccupations concurrentes? Est-ce que j'y pense dans le mauvais sens? Ce problème a-t-il une solution bien connue dans le monde CQS / ESB?

Sinon, comment peut-on décider quel devrait être le "bon niveau" de granularité dans une commande? Existe-t-il un «standard» que l'on peut utiliser comme point de départ - un peu comme 3NF dans les bases de données - et qui ne dévie que lorsqu'un profilage soigneux suggère un avantage de performance potentiellement significatif?

Ou est-ce peut-être une de ces choses qui, malgré plusieurs opinions fortes exprimées par divers experts, n'est vraiment qu'une question d'opinion?

Aaronaught
la source

Réponses:

7

Sur le thème de "chaque changement d'attribut"

Je pense que vous n'avez pas saisi mon argument. M. Udi Dahan dit que vous devez capturer l'intention de l'utilisateur en tant que commande. Un utilisateur final souhaite pouvoir indiquer qu'un client a déménagé. Selon le contexte, cette commande pourrait contenir une identification client, la nouvelle adresse (divisée en rue, numéro de rue, code postal, ...), éventuellement un nouveau numéro de téléphone (pas rare lorsque vous déménagez - peut-être moins avec tous ces téléphones portables) . Ce n'est guère un attribut. Une meilleure question est "comment concevoir des commandes?". Vous les concevez dans une perspective comportementale. Chaque cas d'utilisation, flux, tâche qu'un utilisateur final essaie de terminer, sera capturé dans une ou plusieurs commandes. Les données qui accompagnent ces commandes viennent naturellement, lorsque vous commencez à en raisonner plus en détail. La chose à surveiller est les données qui sont interprétées comme "peut indiquer que vous devez fractionner la commande. J'espère que vous ne trouverez jamais cette norme en ce qui concerne la granularité des commandes. Bonne question cependant!

Yves Reynhout
la source
Cette définition me semble encore très arbitraire; Le modèle conceptuel d'un CSR peut regrouper le statut préféré et le statut martial de la même manière que vous regroupez l'adresse et le code postal ensemble. Je ne veux pas diviser les cheveux, il me semble juste que pour vraiment comprendre si ce sont des comportements différents, il faut être capable de prédire les effets en aval, et OTOH toute l'idée d'ESB et CQS et pub / sous est que vous n'êtes pas censé savoir ou se soucier de ce qui se passe en aval. Merci pour votre réponse, je l'apprécie, même si je ne peux pas dire que je me sente plus éclairé jusqu'à présent ...
Aaronaught
@Aaronaught: La définition est arbitraire. La granularité d'une commande doit être tout ce qui a du sens pour votre scénario particulier . Il n'y a pas de taille unique. Il existe plusieurs directives, telles que l'appariement des commandes pour utiliser des cas ou des tâches ou des actions disponibles dans l'interface utilisateur - une autre consiste à préférer des commandes plus granulaires aux commandes moins granulaires (en particulier, comme Yves l'a dit en se méfiant des données interprétées comme un flux de contrôle logique) - mais pas de règle dure et rapide. Existe-t-il un scénario réel où "un utilisateur pourrait potentiellement mettre à jour des centaines ou des milliers d'entités et d'attributs combinés"?
quentin-star du
Exactement! Ne vous emballez pas. Divisez selon le comportement! Ne placez pas dans la commande des données qui ne correspondent pas à l'intention de la commande / de l'utilisateur final. Et cela ne concerne pas les systèmes en aval.
Yves Reynhout
@qes: Dans nos systèmes, il existe plusieurs scénarios de ce type, très réels et très nécessaires. Pour le dire le plus simplement possible, ils doivent modifier des séquences entières de données et ces séquences n'ont de sens que comme séquences. Bien sûr, ils n'effectuent généralement pas ces modifications enregistrement par enregistrement, ils appliquent un algorithme à l'essentiel, puis corrigent quelques exceptions. Peut-être que ce n'est tout simplement pas un scénario approprié pour CQS, mais cette décision n'est qu'un sous-ensemble de ma question plus large.
Aaronaught
1
@qes: Très bien, et c'est une réponse en soi. Je comprends certainement le concept d'une opération logique (c'est ainsi que les services existants sont modélisés), je suppose que je viens de m'inquiéter du fait que CQS semble changer quelques règles sur la façon dont vous devez définir une opération. La SOA «traditionnelle» semble partir de la définition la plus grossière possible et descendre le cas échéant sur l'échelle d'abstraction; ma compréhension de CQS jusqu'à présent semble indiquer le contraire, à partir de la définition la plus granulaire possible et abstraite si elle ressemble trop à RPC ou à un flux de contrôle.
Aaronaught
2

Le message que Udi essaie de faire passer est que le CQRS est plus qu'un simple CRUD. Pourquoi ai-je créé ce disque? Pourquoi est-ce que je change cet enregistrement? Pourquoi est-il supprimé / marqué comme supprimé?

Les commandes doivent correspondre aux actions / cas d'utilisation que l'utilisateur effectue avec le système et exprimer l'intention de l'action plutôt que de simplement dire changer cela. En outre, il peut sembler que son grain est plus fin, mais il pourrait être beaucoup plus grossier qu'il n'y paraît. Par exemple, la mise à niveau vers le statut Gold peut impliquer une modification de plusieurs attributs et un certain nombre d'autres agrégats peuvent même répondre et changer en réponse à l'événement correspondant.

Le CQRS consiste à capturer la langue de l'entreprise dans la couche Service afin que l'interface utilisateur n'ait pas à se soucier de ce qui se passe lorsque je fais cette mise à niveau Gold ou que l'envoi a été marqué comme non livrable par le transporteur ou que l'employé a été promu au responsable du groupe technologique. Eh bien, techniquement, je parle d'Event Sourcing maintenant, mais vous obtenez ma dérive. Il existe des messages plus distincts, mais ils ne sont pas nécessairement plus fins que le CUD standard.

Michael Brown
la source