Evitar manipulação de eventos duplicados

5

Qual é a melhor maneira de impedir que os eventos sejam tratados mais de uma vez?

Imagine um sistema em que os clientes possam fazer pedidos e, quando for bem-sucedido, um evento OrderCreated seja gerado. Existem alguns processos separados que escutam eventos em um barramento de mensagens.

Um processo é enviar um e-mail para o cliente, suponha que exista a exigência de que o cliente receba um e-mail.

Eu imagino que o processo de envio de e-mail funcionaria da seguinte maneira:

  1. Enviar e-mail
  2. Persistir identificador tratado
  3. Confirme o barramento de mensagens

Mas se a persistência do ID tratado falhar, o cliente receberá vários e-mails.

A única outra solução que pensei foi fazer o seguinte:

  1. Persistir tentativa de lidar com o ID do evento
  2. Enviar e-mail
  3. Persistir identificador do evento
  4. Confirme o barramento de mensagens

Isso me permitiria verificar se o evento tentou ser tratado antes e, se for o caso, erguer algum erro e pedir a um humano para tentar reenviá-lo.

Existe alguma maneira melhor de lidar com problemas como esses? Eu sinto que esse tipo de coisa seria um problema comum, mas não consigo encontrar uma solução robusta.

    
por Nick Williams 18.12.2016 / 19:48
fonte

1 resposta

2

What is the best way of preventing of events from being handled more than once?

A melhor maneira: escreva seu modelo de domínio de modo que o gerenciamento no máximo uma vez seja incorporado à lógica de negócios.

Marc de Graauw, do Ninguém precisa de mensagens confiáveis :

Stating that it is important on the business level that every message is received exactly once, like it is in order processing, means that every message constitutes a unique business transaction.... if every message is a unique business transaction, clearly there must be a unique id on the business level.... if we need such a unique token on the business level, the business level should assert it's uniqueness. Uniqueness on the business level should not be dependent on the transient uniqueness on the message level, but must be a persistent feature of the business message, and business semantics must guarantee it.

Mas esse não é o tipo de exemplo que você está considerando;

One process is to send an email to the customer, assume there is a requirement that the customer MUST be sent an email.

Numa situação em que o MUST; Eu normalmente procuraria pelo menos uma vez lidar com o evento. O processo registra quais emails são obrigatórios e quais foram confirmados.

Por exemplo, o processo que se inscreve em OrderCreated , EmailSent e EmailTimedOut . Na "ordem criada", enviamos um comando para enviar o email e outro para publicar o evento de tempo limite. Ao receber o tempo limite, verificamos se a mensagem do EmailSent apareceu - se não, nós reenviaremos .

Are there any better ways to handle problems like these?

Revise detalhadamente o custo para o negócio dos diferentes modos de falha. Se você DEVE enviar o e-mail, então você precisa que o ack saiba que você fez isso. Se a confirmação puder ser perdida, você precisará reenviá-la. Qual é o custo para o negócio de enviar esse email mais de uma vez? Não se inscreva para a perfeição cara quando a falha é rara e de baixo custo.

I feel like this sort of thing would be a common problem but I can't find a robust solution.

Jonathon Oliver: Mensagens: pelo menos uma vez entrega

One of the primary reasons, if not the primary reason, that messaging systems offer at-least-once delivery rather than exactly-once delivery is that we run into limitations as expressed in the CAP theorem—all “nodes” cannot possibly have a globally consistent snapshot and be available and partition tolerant. There is no unfailing “global brain”.

Veja também: link

    
por 19.12.2016 / 04:39
fonte