Estoy empezando a usar RabbitMQ y AMQP en general.
- Tengo una cola de mensajes
- Tengo varios consumidores, y me gustaría hacer cosas diferentes con el mismo mensaje .
La mayor parte de la documentación de RabbitMQ parece estar centrada en round-robin, es decir, donde un solo mensaje es consumido por un solo consumidor, y la carga se distribuye entre cada consumidor. Este es de hecho el comportamiento que presencio.
Un ejemplo: el productor tiene una sola cola y envía mensajes 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)
})
Y aquí hay un 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)
})
})
})
Si inicio al consumidor dos veces, puedo ver que cada consumidor está consumiendo mensajes alternativos en el comportamiento de todos contra todos. Por ejemplo, veré los mensajes 1, 3, 5 en una terminal, 2, 4, 6 en la otra .
Mi pregunta es:
¿Puedo hacer que cada consumidor reciba los mismos mensajes? Es decir, ¿ambos consumidores reciben el mensaje 1, 2, 3, 4, 5, 6? ¿Cómo se llama esto en AMQP / RabbitMQ? ¿Cómo se configura normalmente?
¿Se hace esto comúnmente? ¿Debería hacer que el intercambio enrute el mensaje en dos colas separadas, con un solo consumidor?
Respuestas:
¿Puedo hacer que cada consumidor reciba los mismos mensajes? Es decir, ¿ambos consumidores reciben el mensaje 1, 2, 3, 4, 5, 6? ¿Cómo se llama esto en AMQP / RabbitMQ? ¿Cómo se configura normalmente?
No, no si los consumidores están en la misma cola. De la guía de conceptos AMQP de RabbitMQ :
Esto parece implicar que el comportamiento de round-robin dentro de una cola es un hecho y no es configurable. Es decir, se requieren colas separadas para que varios consumidores manejen la misma ID de mensaje.
¿Se hace esto comúnmente? ¿Debería hacer que el intercambio enrute el mensaje en dos colas separadas, con un solo consumidor?
No, no lo es, una sola cola / múltiples consumidores con cada consumidor manejando la misma ID de mensaje no es posible. Hacer que el intercambio encamine el mensaje en dos colas separadas es realmente mejor.
Como no necesito un enrutamiento demasiado complejo, un intercambio fanout lo manejará muy bien. No me centré demasiado en los intercambios antes, ya que node-amqp tiene el concepto de un 'intercambio predeterminado' que le permite publicar mensajes en una conexión directamente, sin embargo, la mayoría de los mensajes AMQP se publican en un intercambio específico.
Aquí está mi intercambio de fanout, tanto de envío como de recepción:
fuente
int prefetchCount = 1; channel.basicQos(prefetchCount);
Esto permitirá que cada consumidor reciba un mensaje tan pronto como termine con el anterior. En lugar de recibir mensajes alternos. Nuevamente no resuelve su problema, pero podría ser útil para que la gente lo sepa. ejemplo aquí http://www.rabbitmq.com/tutorials/tutorial-two-java.html bajo Fair DispatchSolo lea el tutorial de rabbitmq . Publica mensajes para intercambiar, no para hacer cola; luego se enruta a las colas apropiadas. En su caso, debe vincular una cola separada para cada consumidor. De esa manera, pueden consumir mensajes de forma completamente independiente.
fuente
Las últimas dos respuestas son casi correctas: tengo toneladas de aplicaciones que generan mensajes que deben terminar con diferentes consumidores, por lo que el proceso es muy simple.
Si desea que varios consumidores reciban el mismo mensaje, realice el siguiente procedimiento.
Cree varias colas, una para cada aplicación que recibirá el mensaje, en cada una de las propiedades de la cola, "enlace" una etiqueta de enrutamiento con el intercambio amq.direct. Cambie su aplicación de publicación para enviar a amq.direct y use la etiqueta de enrutamiento (no una cola). AMQP luego copiará el mensaje en cada cola con el mismo enlace. Funciona de maravilla :)
Ejemplo: Digamos que tengo una cadena JSON que genero, la publico en el intercambio "amq.direct" usando la etiqueta de enrutamiento "new-sales-order", tengo una cola para mi aplicación order_printer que imprime el pedido, tengo un cola para mi sistema de facturación que enviará una copia del pedido y facturará al cliente y tengo un sistema de archivo web donde archivo los pedidos por razones históricas / de cumplimiento y tengo una interfaz web del cliente donde se realiza un seguimiento de los pedidos a medida que se recibe más información una orden.
Por lo tanto, mis colas son: order_printer, order_billing, order_archive y order_tracking. Todos tienen la etiqueta de enlace "new-sales-order" unida a ellos, los 4 obtendrán los datos JSON.
Esta es una forma ideal de enviar datos sin que la aplicación de publicación conozca o se preocupe por las aplicaciones receptoras.
fuente
Sí, cada consumidor puede recibir los mismos mensajes. eche un vistazo a http://www.rabbitmq.com/tutorials/tutorial-three-python.html http://www.rabbitmq.com/tutorials/tutorial-four-python.html http: //www.rabbitmq. com / tutorials / tutorial-five-python.html
para diferentes formas de enrutar mensajes. Sé que son para Python y Java, pero es bueno entender los principios, decidir lo que está haciendo y luego encontrar cómo hacerlo en JS. Parece que quieres hacer un simple fanout ( tutorial 3 ), que envía los mensajes a todas las colas conectadas al intercambio.
La diferencia con lo que está haciendo y lo que quiere hacer es básicamente que va a configurar e intercambiar o escribir fanout. Los despliegues de Fanout envían todos los mensajes a todas las colas conectadas. Cada cola tendrá un consumidor que tendrá acceso a todos los mensajes por separado.
Sí, esto se hace comúnmente, es una de las características de AMPQ.
fuente
El patrón de envío es una relación uno a uno. Si desea "enviar" a más de un receptor, debe utilizar el patrón pub / sub. Consulte http://www.rabbitmq.com/tutorials/tutorial-three-python.html para obtener más detalles.
fuente
RabbitMQ / AMQP: cola única, múltiples consumidores para el mismo mensaje y actualización de página.
fuente
Para obtener el comportamiento que desea, simplemente haga que cada consumidor consuma de su propia cola. Tendrá que usar un tipo de intercambio no directo (tema, encabezado, despliegue) para que el mensaje llegue a todas las colas a la vez.
fuente
Como evalúo su caso es:
Tengo una cola de mensajes (su fuente para recibir mensajes, nombremos q111)
Tengo varios consumidores, y me gustaría hacer cosas diferentes con el mismo mensaje.
Su problema aquí es que mientras esta cola recibe 3 mensajes, el consumidor 1 consume el mensaje 1, otros consumidores B y C consumen los mensajes 2 y 3. Cuando necesite una configuración en la que rabbitmq pase las mismas copias de todos estos tres mensajes (1,2,3) a los tres consumidores conectados (A, B, C) simultáneamente.
Si bien se pueden hacer muchas configuraciones para lograr esto, una forma simple es usar el siguiente concepto de dos pasos:
Nota: Al usar este concepto, no consuma directamente de la cola de origen (q111), ya que los mensajes ya consumidos no se enviarán a su intercambio Fanout.
Si cree que esto no satisface sus requisitos exactos ... no dude en publicar sus sugerencias :-)
fuente
Si está utilizando la biblioteca amqplib como yo, tienen un ejemplo útil de una implementación del tutorial Publicar / Suscribir RabbitMQ que puede encontrar útil.
fuente
Creo que deberías revisar el envío de tus mensajes usando el despliegue intercambiador de . De esta manera, recibirá el mismo mensaje para diferentes consumidores, debajo de la tabla RabbitMQ está creando diferentes colas para cada uno de estos nuevos consumidores / suscriptores.
Este es el enlace para ver el ejemplo del tutorial en javascript https://www.rabbitmq.com/tutorials/tutorial-one-javascript.html
fuente
Hay una opción interesante en este escenario que no he encontrado en las respuestas aquí.
Puede bloquear mensajes con la función "solicitar" en un consumidor para procesarlos en otro. En términos generales, no es una forma correcta, pero tal vez sea lo suficientemente bueno para alguien.
https://www.rabbitmq.com/nack.html
¡Y cuidado con los bucles (cuando todos los concumers nack + mensaje de solicitud)!
fuente