Comment déterminer si un message doit être un message de commande ou un message d'événement?

11

Deux modèles d'intégration d'entreprise sont le message de commande et le message d'événement . Je travaille sur un système dans lequel nous utilisons la messagerie non seulement pour l'intégration avec d'autres systèmes, mais pour la communication interne entre les services. Il est censé être un système cohérent à terme , et les services sont censés s'ignorer les uns les autres (à l'exception de quelques services spécialisés). En tant que tel, nous essayons d'éviter les choses qui ressemblent à des appels de procédure à distance (RPC ou RPI). Nous avons un système de bus et de middleware orienté message, et tous les messages sont diffusés.

Nous avons tendance à nommer nos messages comme des événements, c'est-à-dire comme une phrase parfaite dans le passé, par exemple PurchaseOrderShipped. Cependant, les événements ne sont souvent ajoutés que lorsque certains autres services ont besoin de les connaître, et au début, souvent un seul service s'en soucie. De plus, parfois ce service émet un événement en conséquence, qui est écouté par le premier service. Ainsi, si je schématisais l'interaction, cela ressemblerait beaucoup plus au diagramme du message de commande dans le lien ci-dessus (ou même au diagramme RPC) qu'à celui du message d'événement, mais encore une fois, cela n'est pas réellement implémenté avec messagerie directe mais diffusée sur un bus. Ajoutez à cela le fait que j'ai récemment vu certains messages ajoutés qui sont nommés comme des commandes, c'est-à-dire une phrase dans l'impératif, par exemple BillShippedPurchaseOrder.

La chose étrange est que les noms des messages et la façon dont ils circulent ne sont pas modifiés selon qu'ils sont nommés en tant qu'événement ou en tant que commande. Alors, comment déterminer si quelque chose doit être un message de commande ou un événement? S'agit-il simplement d'une différence de sémantique et de dénomination, ou existe-t-il une réelle différence d'implémentation entre les messages de commande et d'événement? Étant donné que tous nos messages sont diffusés, cela signifie-t-il qu'aucun d'eux n'est vraiment un message de commande?

Kazark
la source

Réponses:

11

Il existe une différence subtile mais importante entre les commandes et les événements. Une commande a une présomption de réponse alors qu'un événement ne présume pas de réponse, c'est simplement une déclaration.

Pour être moins abstrait:

ShipOrderest une commande et l'expéditeur ShipOrderattendra probablement une réponse quelconque.
OrderShippedest une déclaration et il est peu probable que l'expéditeur s'attende à une réponse, tout comme GoodJob!une réponse inutile dans cet exemple.

Si vous concevez vos systèmes pour n'attendre que des messages d'événement, cela n'a pas forcément d'importance pour la conception du système ce que vous appelez les messages. Les développeurs peuvent être déroutés par le nom d'un message, mais les systèmes répondent très bien quelle que soit la convention que vous suivez pour nommer les choses.

Mais il ne semble pas que vos collègues développeurs suivent le modèle de message uniquement événementiel. Si les services attendent des réponses aux "messages d'événement" qu'ils envoient, alors ils envoient réellement des messages de commande. Ce n'est pas un gros problème, et je peux penser à de nombreux cas où des commandes telles que des demandes d'informations seraient nécessaires. Mais vous aurez un mal de tête sémantique si vous vous attendiez à ne voir que les messages d'événement.

La diffusion de messages n'a pas vraiment d'impact sur le fait qu'un message soit une commande ou un événement. Généralement, vous ne diffusez pas de commandes car cela duplique l'effort. Mais il n'y a rien à dire que vous ne pourriez pas. Les premiers protocoles réseau diffusaient chaque paquet et les récepteurs devaient être suffisamment intelligents pour savoir quand ignorermessages paquets qui ne leur appartenaient pas.


la source
Comment implémentez-vous les request for informationfonctionnalités? Il semble naturel d'utiliser quelque chose comme getUserInfo(uid)qui est un message de commande attendant une réponse. Je sais que les messages de commande introduisent le couplage, mais malheureusement dans ce cas, je ne vois pas comment l'implémenter avec des messages d'événement. Ou est-ce bien de s'en tenir aux messages de commande dans certaines occasions comme celle-ci?
du369
@ du369 Désolé, mais je ne suis pas tout à fait à la suite de votre question. On dirait que vous essayez de créer une commande mais que vous utilisez des événements?
Oui, à peu près ça. Dans le lien fourni dans la réponse de Lee, la même fonctionnalité est implémentée de deux manières différentes. L'un utilise le CancelPolicyRequestmessage qui est une commande. L'autre approche utilise deux messages d'événement, à savoir InvoicePastDueNotificationet PolicyCancelledNotification. Je me demande donc s'il est possible de modifier les commandes comme le getUserInfo(uid)style des messages d'événement et comment suis-je censé le faire.
du369
1
@ du369 Quelque chose, quelque part doit exécuter l' Actionassocié à la commande. Il y a deux étapes associées à une commande. 1) La commande est-elle nécessaire (par exemple, la politique a expiré), et 2) exécuter la commande (par exemple, annuler la politique). Si le Actorqui détermine si la commande est nécessaire ET peut s'exécuter, cela Actorpermet d'envoyer des messages d'événement. Sinon, tout ce qui détermine que la commande est nécessaire est requis pour envoyer un événement de commande.
5

Un message d'événement est quelque chose qui vient de se produire. Vous informez de l'événement qui vient de se produire.

Un message de commande est un message qui attend quelque chose à faire. Il peut ou non attendre une réponse.

Quand utiliser ce qui se résume au couplage et la différence n'apparaîtra qu'avec le temps à mesure que les systèmes évoluent. Privilégier les événements aux commandes entraîne moins de couplage. L'émetteur de l'événement ne se soucie pas du consommateur. Dans un modèle de commande, l'appelant sait et dépend donc de l'existence du fournisseur.

Bill Poole suggère d'éviter les messages de commande tous ensemble: http://bill-poole.blogspot.com.au/2008/04/avoid-command-messages.html

http://bill-poole.blogspot.com.au/

Lee Simpson
la source
Lee, merci pour votre réponse, mais je comprends la théorie derrière la définition de chacun. Ma question est de savoir comment appliquer cela dans la vie réelle --- quand informer qu'un événement s'est produit, ce qui se traduit souvent par une action, et quand demander que quelque chose soit fait.
Kazark
Je pense que cela se résume au couplage et la différence n'apparaîtra qu'avec le temps à mesure que les systèmes évoluent. Privilégier les événements aux commandes entraîne moins de couplage. L'émetteur de l'événement ne se soucie pas du consommateur. Dans un modèle de commande, l'appelant sait et dépend donc de l'existence du fournisseur. Avez-vous lu les articles de Bill Poole?
Lee Simpson
Lee, merci, c'est utile; en fait, je vous suggère de modifier le contenu de votre commentaire dans votre réponse, y compris un lien vers les articles Poole (que je ne suis pas sûr d'avoir lu).
Kazark