RabbitMQ – Message order of delivery

Eu preciso escolher um novo corretor de fila para o meu novo projeto.

Desta vez eu preciso de uma fila escalável que suporte pub / sub, e manter a ordenação de mensagens é uma obrigação.

Eu li o comentário de Alexis: ele escreve:

“De fato, achamos que o RabbitMQ fornece pedidos mais fortes do que o Kafka”

Eu li a seção de pedidos de mensagens no rabbitmq docs:

“As mensagens podem ser retornadas para a fila usando methods AMQP que apresentam um parâmetro de nova geração (basic.recover, basic.reject e basic.nack) ou devido a um fechamento do canal enquanto mantém mensagens não confirmadas … Com o release 2.7.0 e posterior ainda é possível para os consumidores individuais observar as mensagens fora de ordem se a fila tiver vários assinantes, devido às ações de outros assinantes que podem enfileirar as mensagens.Do ponto de vista da fila, as mensagens são sempre mantidas na ordem de publicação. ”

Se eu precisar manipular mensagens pelo seu pedido, só posso usar o rabbitMQ com uma fila exclusiva para cada consumidor?

O RabbitMQ ainda é considerado uma boa solução para o enfileiramento de mensagens ordenadas?

   

    Bem, vamos dar uma olhada mais de perto no cenário que você está descrevendo acima. Acho importante colar a documentação imediatamente antes do snippet em sua pergunta para fornecer contexto:

    A seção 4.7 da especificação principal do AMQP 0-9-1 explica as condições sob as quais a ordenação é garantida: as mensagens publicadas em um canal, passando por uma troca e uma fila e um canal de saída serão recebidas na mesma ordem em que foram enviadas. O RabbitMQ oferece garantias mais fortes desde o lançamento 2.7.0.

    As mensagens podem ser retornadas para a fila usando methods AMQP que apresentam um parâmetro de nova geração (basic.recover, basic.reject e basic.nack) ou devido a um fechamento de canal enquanto mantém mensagens não reconhecidas. Qualquer um desses cenários fazia com que as mensagens fossem reescritas na parte de trás da fila para liberações do RabbitMQ anteriores a 2.7.0. A partir do RabbitMQ versão 2.7.0, as mensagens são sempre mantidas na fila na ordem de publicação, mesmo na presença de novo enfileiramento ou fechamento do canal. (enfase adicionada)

    Assim, fica claro que o RabbitMQ, a partir do 2.7.0, está melhorando drasticamente a especificação original do AMQP no que diz respeito à ordenação de mensagens.

    Com vários consumidores (paralelos), a ordem de processamento não pode ser garantida.
    O terceiro parágrafo (colado na pergunta) passa a dar um aviso, que parafraseando: “se você tem vários processadores na fila, não há mais garantia de que as mensagens serão processadas em ordem”. Tudo o que eles estão dizendo aqui é que o RabbitMQ não pode desafiar as leis da matemática.

    Considere uma linha de clientes em um banco. Esse banco específico se orgulha de ajudar os clientes na ordem em que eles entraram no banco. Os clientes fazem fila em uma fila e são atendidos pelos próximos 3 checkboxs disponíveis.

    Esta manhã, aconteceu que todos os três checkboxs se tornaram disponíveis ao mesmo tempo, e os próximos 3 clientes se aproximaram. De repente, o primeiro dos três checkboxs ficou gravemente doente e não conseguiu terminar de atender ao primeiro cliente da linha. No momento em que isso aconteceu, o checkbox 2 terminou com o cliente 2 e o checkbox 3 já tinha começado a atender o cliente 3.

    Agora, uma das duas coisas pode acontecer. (1) O primeiro cliente na fila pode voltar ao início da linha ou (2) o primeiro cliente pode antecipar-se ao terceiro cliente, fazendo com que o checkbox pare de trabalhar no terceiro cliente e comece a trabalhar no primeiro. Esse tipo de lógica de preempção não é suportada pelo RabbitMQ nem por qualquer outro intermediário de mensagem que eu conheça. Em ambos os casos, o primeiro cliente, na verdade, não acaba sendo ajudado primeiro – o segundo cliente o faz, sendo sortudo o suficiente para obter um bom e rápido contador. A única maneira de garantir que os clientes recebam ajuda é ter um checkbox ajudando os clientes, um de cada vez, o que causará grandes problemas de atendimento ao cliente no banco.

    Espero que isso ajude a ilustrar o problema que você está perguntando. Não é possível garantir que as mensagens sejam tratadas em ordem em todos os casos possíveis, uma vez que você tem vários consumidores. Não importa se você tem várias filas, vários consumidores exclusivos, diferentes corretores, etc. – não há como garantir a priori que as mensagens são respondidas em ordem com vários consumidores. Mas o RabbitMQ fará um ótimo esforço.

    A ordenação de mensagens é preservada no Kafka, mas apenas nas partições, e não no global. Se os seus dados precisarem de ordenação global e partições, isso dificultará as coisas. No entanto, se você só precisa se certificar de que todos os mesmos events para o mesmo usuário, etc … acabam na mesma partição para que eles sejam ordenados corretamente, você pode fazê-lo. O produtor é responsável pela partição para a qual eles escrevem, portanto, se você for capaz de particionar logicamente seus dados, isso pode ser preferível.

    Eu acho que há duas coisas nesta questão que não são semelhantes, ordem de consumo e ordem de processamento.

    Filas de mensagens podem – em certa medida – dar-lhe uma garantia de que as mensagens serão consumidas em ordem, mas não podem, no entanto, dar-lhe quaisquer garantias sobre a ordem do seu processamento.

    A principal diferença aqui é que existem alguns aspectos do processamento de mensagens que não podem ser determinados no momento do consumo, por exemplo:

    • Como mencionado um consumidor pode falhar durante o processamento, aqui a ordem de consumo da mensagem estava correta, no entanto, o consumidor não conseguiu processá-lo corretamente, o que fará voltar para a fila, e até agora a ordem de consumo ainda está intacta, mas don ‘ Não sei como a ordem de processamento é agora

    • Se por “processamento” queremos dizer que a mensagem agora está descartada e terminou o processamento completamente, então considere o caso quando seu tempo de processamento não é linear, ou seja, processar uma mensagem demora mais que outra, então se a mensagem 3 demorar mais no processamento que antecipada, então as mensagens 4 e 5 podem ser consumidas e terminar o processamento antes que a mensagem 3

    Portanto, mesmo que você consiga recolocar a mensagem na frente da fila (o que viola a ordem de consumo), você ainda não pode garantir que todas as mensagens antes da próxima mensagem tenham terminado o processamento.

    Se você quiser garantir a ordem de processamento, então:

    1. Tem apenas uma instância do consumidor em todos os momentos
    2. Ou não use uma fila de mensagens e faça o processamento em um método de bloqueio síncrono, o que pode parecer ruim, mas em muitos casos e os requisitos de negócios são completamente válidos e às vezes até críticos