Estou apenas começando a usar o RabbitMQ e o AMQP em geral.
- Eu tenho uma fila de mensagens
- Tenho vários consumidores, que gostaria de fazer coisas diferentes com a mesma mensagem .
A maior parte da documentação do RabbitMQ parece estar focada no round-robin, ou seja, onde uma única mensagem é consumida por um único consumidor, com a carga sendo distribuída entre cada consumidor. Este é realmente o comportamento que eu testemunho.
Um exemplo: o produtor possui uma única fila e envia mensagens a cada 2 segundos:
var amqp = require('amqp');
var connection = amqp.createConnection({ host: "localhost", port: 5672 });
var count = 1;
connection.on('ready', function () {
var sendMessage = function(connection, queue_name, payload) {
var encoded_payload = JSON.stringify(payload);
connection.publish(queue_name, encoded_payload);
}
setInterval( function() {
var test_message = 'TEST '+count
sendMessage(connection, "my_queue_name", test_message)
count += 1;
}, 2000)
})
E aqui está um consumidor:
var amqp = require('amqp');
var connection = amqp.createConnection({ host: "localhost", port: 5672 });
connection.on('ready', function () {
connection.queue("my_queue_name", function(queue){
queue.bind('#');
queue.subscribe(function (message) {
var encoded_payload = unescape(message.data)
var payload = JSON.parse(encoded_payload)
console.log('Recieved a message:')
console.log(payload)
})
})
})
Se eu iniciar o consumidor duas vezes, posso ver que cada consumidor está consumindo mensagens alternativas no comportamento de rodízio. Por exemplo, vou ver as mensagens 1, 3, 5 em um terminal, 2, 4, 6 no outro .
Minha pergunta é:
Posso fazer com que cada consumidor receba as mesmas mensagens? Ou seja, ambos os consumidores recebem a mensagem 1, 2, 3, 4, 5, 6? Como é chamado o AMQP / RabbitMQ? Como é configurado normalmente?
Isso é comumente feito? Devo apenas fazer com que o Exchange direcione a mensagem para duas filas separadas, com um único consumidor?
Respostas:
Posso fazer com que cada consumidor receba as mesmas mensagens? Ou seja, ambos os consumidores recebem a mensagem 1, 2, 3, 4, 5, 6? Como é chamado o AMQP / RabbitMQ? Como é configurado normalmente?
Não, não se os consumidores estiverem na mesma fila. No guia de conceitos AMQP do RabbitMQ :
Isso parece implicar que o comportamento de rodízio em uma fila é um dado e não configurável. Ou seja, filas separadas são necessárias para que o mesmo ID de mensagem seja tratado por vários consumidores.
Isso é comumente feito? Devo apenas fazer com que o Exchange direcione a mensagem para duas filas separadas, com um único consumidor?
Não, não é, fila única / vários consumidores, com cada consumidor manipulando a mesma ID de mensagem não é possível. Ter a rota de troca da mensagem em duas filas separadas é realmente melhor.
Como não preciso de roteamento muito complexo, uma troca de fanout lidará com isso muito bem. Não foquei muito em Trocas anteriormente, pois o node-amqp tem o conceito de 'troca padrão', permitindo publicar mensagens diretamente em uma conexão, no entanto, a maioria das mensagens AMQP é publicada em uma troca específica.
Aqui está minha troca de fãs, tanto enviando quanto recebendo:
fonte
int prefetchCount = 1; channel.basicQos(prefetchCount);
Isso permitirá que cada consumidor receba uma mensagem assim que terminar com a anterior. Em vez de receber mensagens alternadas. Novamente, não resolve o seu problema, mas pode ser útil para as pessoas saberem. exemplo aqui http://www.rabbitmq.com/tutorials/tutorial-two-java.html em Fair DispatchBasta ler o tutorial rabbitmq . Você publica mensagem para troca, não para fila; em seguida, é roteado para as filas apropriadas. No seu caso, você deve vincular uma fila separada para cada consumidor. Dessa forma, eles podem consumir mensagens de forma totalmente independente.
fonte
As duas últimas respostas estão quase corretas - eu tenho vários aplicativos que geram mensagens que precisam terminar com diferentes consumidores, portanto o processo é muito simples.
Se você desejar vários consumidores com a mesma mensagem, siga o procedimento a seguir.
Crie várias filas, uma para cada aplicativo que receberá a mensagem, nas propriedades de cada fila, "vincule" uma marca de roteamento à troca amq.direct. Altere seu aplicativo de publicação para enviar para amq.direct e use a tag de roteamento (não uma fila). O AMQP copiará a mensagem em cada fila com a mesma ligação. Funciona como um encanto :)
Exemplo: digamos que eu possuo uma string JSON que eu gere, eu a publico na central "amq.direct" usando a tag de roteamento "new-sales-order", tenho uma fila para meu aplicativo order_printer que imprime o pedido, tenho um fila para o meu sistema de cobrança que enviará uma cópia do pedido e faturará ao cliente, e eu tenho um sistema de arquivamento na web em que arquivo os pedidos por razões históricas / de conformidade e tenho uma interface da web do cliente em que os pedidos são rastreados quando outras informações são exibidas. uma ordem.
Então, minhas filas são: order_printer, order_billing, order_archive e order_tracking Todos têm a tag de ligação "new-sales-order" vinculada a eles, todos os 4 obterão os dados JSON.
Essa é a maneira ideal de enviar dados sem que o aplicativo de publicação conheça ou se preocupe com os aplicativos de recebimento.
fonte
Sim, cada consumidor pode receber as mesmas mensagens. consulte http://www.rabbitmq.com/tutorials/tutorial-three-python.html http://www.rabbitmq.com/tutorials/tutorial-four-python.html http: //www.rabbitmq. com / tutoriais / tutorial-cinco-python.html
para diferentes maneiras de rotear mensagens. Eu sei que eles são para python e java, mas é bom entender os princípios, decidir o que você está fazendo e depois descobrir como fazê-lo em JS. Parece que você deseja fazer um fanout simples ( tutorial 3 ), que envia as mensagens para todas as filas conectadas à central.
A diferença com o que você está fazendo e com o que você quer fazer é basicamente que você irá configurar e trocar ou digitar fanout. As trocas de fanout enviam todas as mensagens para todas as filas conectadas. Cada fila terá um consumidor que terá acesso a todas as mensagens separadamente.
Sim, isso geralmente é feito, é um dos recursos do AMPQ.
fonte
O padrão de envio é um relacionamento um para um. Se você deseja "enviar" para mais de um receptor, deve usar o padrão pub / sub. Consulte http://www.rabbitmq.com/tutorials/tutorial-three-python.html para obter mais detalhes.
fonte
RabbitMQ / AMQP: fila única, vários consumidores para a mesma mensagem e atualização de página.
fonte
Para obter o comportamento desejado, basta fazer com que cada consumidor consuma em sua própria fila. Você precisará usar um tipo de troca não direta (tópico, cabeçalho, fanout) para obter a mensagem para todas as filas de uma só vez.
fonte
Como eu avalio o seu caso, é:
Eu tenho uma fila de mensagens (sua fonte para receber mensagens, vamos chamá-lo de q111)
Tenho vários consumidores, que gostaria de fazer coisas diferentes com a mesma mensagem.
Seu problema aqui é que, enquanto 3 mensagens são recebidas por essa fila, a mensagem 1 é consumida por um consumidor A, outros consumidores B e C consomem as mensagens 2 e 3. Onde você precisar de uma configuração em que rabbitmq passe as mesmas cópias de todas essas três mensagens (1,2,3) para todos os três consumidores conectados (A, B, C) simultaneamente.
Embora muitas configurações possam ser feitas para isso, uma maneira simples é usar o seguinte conceito de duas etapas:
Nota: Ao usar esse conceito, não consuma diretamente da fila de origem (q111), pois as mensagens já consumidas não serão enviadas para a sua troca de Fanout.
Se você acha que isso não atende exatamente aos seus requisitos ... fique à vontade para postar suas sugestões :-)
fonte
Se você estiver usando a biblioteca amqplib como eu, eles têm um exemplo útil de uma implementação do tutorial Publish / Subscribe RabbitMQ que você pode achar útil.
fonte
Eu acho que você deve verificar o envio de suas mensagens usando o trocador de fan-out . Dessa forma, você receberá a mesma mensagem para diferentes consumidores, abaixo da tabela, o RabbitMQ está criando filas diferentes para cada um desses novos consumidores / assinantes.
Este é o link para ver o exemplo do tutorial em javascript https://www.rabbitmq.com/tutorials/tutorial-one-javascript.html
fonte
Há uma opção interessante nesse cenário que não encontrei nas respostas aqui.
Você pode Nack mensagens com o recurso "refileirar" em um consumidor para processá-las em outro. De um modo geral, não é o caminho certo, mas talvez seja bom o suficiente para alguém.
https://www.rabbitmq.com/nack.html
E cuidado com os loops (quando todos os concorrentes concordam em remarcar mensagem)!
fonte