CQRS + Event Sourcing: (é correto) Os comandos geralmente são comunicados ponto a ponto, enquanto os Eventos de Domínio são comunicados através de pub / sub?


12

Estou basicamente tentando entender o conceito de CQRS e conceitos relacionados.

Embora o CQRS não incorpore necessariamente o Messaging e o Event Sourcing, parece ser uma boa combinação (como pode ser visto com muitos exemplos / postagens de blog combinando esses conceitos)

Dado um caso de uso para uma alteração de estado de alguma coisa (digamos, para atualizar uma Pergunta no SO), você consideraria o fluxo a seguir correto (como na melhor prática)?

O sistema emite um UpdateQuestionCommand agregado, que pode ser separado em alguns comandos menores: UpdateQuestion, direcionado à Raiz Agregada de Perguntas, e UpdateUserAction (para contar pontos, etc.), direcionado à Raiz Agregada do Usuário. Eles são enviados de forma assíncrona usando mensagens ponto a ponto.

As raízes agregadas fazem o que precisam e, se tudo der certo, os eventos QuestionUpdated e UserActionUpdated, respectivamente, que contêm o estado terceirizado para um armazenamento de eventos.

Esses eventos também são colocados em uma fila de pub / sub para transmissão. Qualquer assinante (entre os quais provavelmente um ou vários projetores que criam as visualizações de leitura) é livre para se inscrever nesses eventos.

A questão geral: é de fato a melhor prática que os comandos sejam comunicados ponto a ponto (ou seja: o receptor é conhecido) enquanto os eventos são transmitidos (ou seja, o (s) receptor (es) é desconhecido)?

Supondo o que foi dito acima, qual seria a vantagem / desvantagem de permitir que os Comandos fossem transmitidos através de pub / sub em vez de ponto a ponto?

Por exemplo: ao transmitir comandos enquanto estiver usando Saga's pode ser um problema, pois o papel de mediação que um Saga precisa desempenhar em caso de falha de uma das raízes agregadas é prejudicado, porque a saga não sabe quais raízes agregadas participam para começar. .

Por outro lado, vejo vantagens (flexibilidade) quando comandos de transmissão são permitidos.


Bem escrito pergunta btw.
Dav

Respostas:


18

Exoneração de responsabilidade: Estou apenas dando meus primeiros passos no mundo do CQRS, mas posso oferecer meu entendimento atual sobre o assunto e veremos se outros confirmam. Tudo o que escrevo abaixo tem um tema subjacente "como eu o vejo" e não é autoritário.

O caso de 80%

Para responder à sua pergunta, os comandos são de fato um ponto a ponto. Quando um comando entra em um controlador (MVC webapp), esse controlador solicita a um distribuidor que encontre um e apenas um manipulador de comando apropriado e delega o trabalho para esse manipulador.

Por que não publicar?

É uma questão de responsabilidade . Se algo envia um comando, isso implica a expectativa de que seja cumprido. Se você simplesmente publica e espera que algo em algum lugar o pegue e atue, não há garantia de que será esse o caso. Por extrapolação, você também não sabe se vários manipuladores não decidem agir em um comando, possivelmente resultando na mesma alteração sendo aplicada mais de uma vez.

Os eventos, por outro lado, são de natureza informativa e é razoável esperar que zero, dois ou mais componentes estejam interessados ​​em um evento específico. Realmente não nos importamos no escopo de fazer a alteração solicitada.

Exemplo

Isso pode ser comparado à vida real. Se você tiver três filhos, entre em uma sala e simplesmente grite "Limpe o banheiro", você não tem garantia de que alguém o fará, e realiza se não for feito duas vezes (se você tiver filhos obedientes ;-) se sair melhor se você designar uma criança específica para fazer o que deseja.

Quando essa criança termina seu trabalho, no entanto, é conveniente que grite "o banheiro foi limpo", para que todos que queiram escovar os dentes saibam que agora podem fazê-lo.


faz muito sentido. Excelente analogia :) #
22412 Geert-Jan

Você me perdeu no ... When a command enters a controller (MVC webapp)-? Você está usando o RESTful? ou alguns pontos de extremidade da API híbrida? Você pode adicionar um exemplo por favor
Piotr Kula

@ppumkin, usamos um ponto de extremidade WebAPI que seria chamado pelo nosso aplicativo da Web toda vez que fosse necessário executar um comando. Por exemplo. se o usuário quisesse adicionar um comentário, o aplicativo da Web enviaria uma solicitação POST para example.com/api/Post/AddPostComment.
Dav

1

Concordo que um sistema iniciador geralmente nunca esperaria que um comando fosse transacionado por vários sistemas de destino:

  • Os comandos geralmente nunca 'enviam e rezam' - o sistema iniciador de um comando geralmente deseja feedback assíncrono à medida que o progresso e o resultado do comando ocorrem (por exemplo, eventos de estado como acknowledgemente bem-sucedidos completionou failurepodem ser publicados pelo sistema direcionado para informar o iniciador sistema).
  • Se vários sistemas de destino estivessem envolvidos, o sistema inicial receberia vários resultados (possivelmente contraditórios) para o comando (por exemplo, o destino 1 foi bem-sucedido, mas o destino 2 falhou). Isso exigiria complexidade adicional para determinar o estado real do comando original (por exemplo, a transação do comando seria considerada bem-sucedida apenas se todos os destinos tivessem sucesso? O comando precisaria ser revertido ou compensado em destinos bem-sucedidos se um dos destinos falhasse? etc.) Isso introduziria acoplamentos e complexidade indesejáveis ​​entre os sistemas inicial e de destino.

No entanto, ainda há mérito em poder contratar consumidores adicionais (não transacionais e geralmente bastante promíscuos) que "escutam" os comandos emitidos entre os sistemas

  • Finalidades de auditoria
  • Instrumentação e métricas operacionais (por exemplo, carga, análise de negócios, etc.)
  • Processadores de eventos complexos ou processamento de eventos de fluxo 'bisbilhoteiros' - esses sistemas podem detectar erros ou irregularidades nos comandos (por exemplo, frequência de comandos ou correlação entre diferentes combinações de comandos e eventos) e podem acionar alertas ou ações corretivas (geralmente no mais tipos diferentes de comandos).
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.