Prólogo
Modo de cola de trabajo:
Un productor, varios consumidores, cada consumidor recibe mensajes únicos. Cuando ejecuta varios subprocesos de trabajo, estos mensajes se compartirán entre los subprocesos de trabajo y se sondearán de forma predeterminada. En pocas palabras, el modo de cola de trabajo es el mismo que el modo simple, excepto que el modo simple tiene un productor y un consumidor, y el modo de cola de trabajo tiene un productor y múltiples consumidores.
Aquí se inician tres hilos, a saber, productor, consumidor 1 y consumidor 2. Los códigos de productor y consumidor son básicamente los mismos que el modo simple anterior , con ligeras modificaciones
Lograr
Productor:
static void Main ( string [] args) { // 1. Cree una fábrica de conexiones ConnectionFactory factory = new ConnectionFactory () { HostName = " 127.0.0.1 " , UserName = " guest " , Password = " guest " }; // 2. Crear conexión var connection = factory.CreateConnection (); // 3. Crear una tubería var channel =connection.CreateModel (); // 4. Canal de cola de sentencias. QueueDeclare ( " simple " , false , false , false , null ); for ( int i = 0 ; i < 20 ; i ++ ) { string msg = $ " 第 { i + 1} messages " ; // 5. Publicar canal de mensajes.BasicPublish ( " " , " simple " , null , Encoding.UTF8.GetBytes (msg)); Console.WriteLine ($ " 已 发送 消息 : {msg} " ); Hilo Dormir ( 1000 ); } canal.Cerrar (); conexión.Cerrar (); Console.ReadKey (); }
Consumidores 1, 2:
vacío estático Main ( string [] args) { // 初始化 工厂 Factory Factory Connection = nuevo ConnectionFactory () { HostName = " 127.0.0.1 " , UserName = " guest " , Password = " guest " }; // 创建 连接 using (IConnection connection = factory.CreateConnection ()) { using (IModel channel =connection.CreateModel ()) { // Declarar canal de cola.QueueDeclare ( " simple " , false , false , false , null ); // Crear objeto de consumidor var consumer = new EventingBasicConsumer (channel); consumer.Received + = (model , e) => { byte [] message = e.Body.ToArray (); Console.WriteLine ( " Recibir mensaje: " +Encoding.UTF8.GetString (mensaje)); // Devuelve el mensaje de confirmación channel.BasicAck (e.DeliveryTag, false ); }; // El consumidor comienza a escuchar channel.BasicConsume ( " simple " , false , consumer); Console.ReadLine (); } } }
El resultado
En este momento, el consumidor P escribe un mensaje en la cola, y el consumidor 1 y el consumidor 2 enviarán de manera justa, de la siguiente manera:
Puede ver que un consumidor recibe mensajes singulares y otro consumidor recibe mensajes pares. Esta situación se debe a que RabbitMQ comienza a distribuir mensajes después de ingresar a la cola. No verifica si cada consumidor tiene la cantidad de mensajes no confirmados, sino que simplemente los distribuye ciegamente a cada consumidor en promedio.
Programación de mensajes
Ahora cambiamos este comportamiento y establecemos BasicQos
Model.BasicQos (0,1, falso);
Esto significa que RabbitMQ no enviará mensajes nuevos a este consumidor hasta que el consumidor procese y confirme el mensaje anterior. Cuando no se confirma el mensaje del consumidor 1, se omitirá el consumidor 1 y se enviará al consumidor 2.
El código del consumidor ahora es así:
vacío estático Main ( string [] args) { // 初始化 工厂 Factory Factory Connection = nuevo ConnectionFactory () { HostName = " 127.0.0.1 " , UserName = " guest " , Password = " guest " }; // 创建 连接 using (IConnection connection = factory.CreateConnection ()) { using (IModel channel =connection.CreateModel ()) { // Declara el canal de la cola.QueueDeclare ( " simple " , false , false , false , null ); // Informa a RabbitMQ que cuando no se reciba la señal de confirmación del mensaje del Trabajador actual, ya no se distribuirá al mensaje Para garantizar una programación justa. channel.BasicQos (prefetchSize: 0 , prefetchCount: 1 , global : false ); // Crear objeto de consumidor var consumer = new EventingBasicConsumer (channel); consumer.Received + = (model, e) => { byte [] message = e.Body.ToArray (); Console.WriteLine ( " Recibir mensaje: " + Encoding.UTF8.GetString (mensaje)); // Devuelve el mensaje de confirmación channel.BasicAck (e.DeliveryTag, false ); }; // El consumidor comienza a escuchar channel.BasicConsume ( " simple " , false , consumer); Console.ReadLine (); } } }
Se puede ver que la recepción del mensaje actual es enviar mensajes a cualquier consumidor que esté inactivo (el procesamiento se completa y se confirma el mensaje), por lo que la secuencia de mensajes ya no es que un consumidor reciba mensajes singulares, y un consumidor reciba incluso mensajes.