Foreword
Work queue mode:
A producer, multiple consumers, each consumer gets unique messages, when you run multiple worker threads, these messages will be shared among the worker threads, and polled by default Simply put, the work queue mode is the same as the simple mode, except that the simple mode has one producer and one consumer, and the work queue mode has one producer and multiple consumers.
Three threads are started here, namely producer, consumer 1, and consumer 2. The producer and consumer codes are basically the same as the previous simple mode , with slight modifications
achieve
Producer:
static void Main ( string [] args) { // 1. Create a connection factory ConnectionFactory factory = new ConnectionFactory () { HostName = " 127.0.0.1 " , UserName = " guest " , Password = " guest " }; // 2. Create connection var connection = factory.CreateConnection (); // 3. Create a pipe var channel =connection.CreateModel (); // 4. Statement queue channel.QueueDeclare ( " simple " , false , false , false , null ); for ( int i = 0 ; i < 20 ; i ++ ) { string msg = $ " 第 { i + 1} messages " ; // 5. Publish message channel.BasicPublish ( " " , " simple " , null , Encoding.UTF8.GetBytes (msg)); Console.WriteLine($"已发送消息:{msg}"); Thread.Sleep(1000); } channel.Close(); connection.Close(); Console.ReadKey(); }
Consumers 1, 2:
static void Main(string[] args) { //初始化工厂 ConnectionFactory factory = new ConnectionFactory() { HostName = "127.0.0.1", UserName = "guest", Password = "guest" }; //创建连接 using (IConnection connection = factory.CreateConnection()) { using (IModel channel =connection.CreateModel ()) { // Declare queue channel.QueueDeclare ( " simple " , false , false , false , null ); // Create consumer object var consumer = new EventingBasicConsumer (channel); consumer.Received + = (model , e) => { byte [] message = e.Body.ToArray (); Console.WriteLine ( " Receive message: " +Encoding.UTF8.GetString (message)); // Return message confirmation channel.BasicAck (e.DeliveryTag, false ); }; // The consumer starts listening channel.BasicConsume ( " simple " , false , consumer); Console.ReadLine (); } } }
result
At this time, consumer P writes a message to the queue, and consumer 1 and consumer 2 will dispatch fairly, as follows:
You can see that one consumer receives singular messages and another consumer receives even messages. This situation is because RabbitMQ starts to distribute messages after entering the queue. It does not check whether each consumer has the number of unconfirmed messages, but just blindly distributes to each consumer on average.
Message scheduling
Now we change this behavior and set BasicQos
Model.BasicQos (0,1, false);
This means that RabbitMQ will not send new messages to this consumer until the consumer processes and confirms the previous message. When the message of consumer 1 is not confirmed, then consumer 1 will be skipped and sent to consumer 2.
The consumer code is now like this:
static void Main(string[] args) { //初始化工厂 ConnectionFactory factory = new ConnectionFactory() { HostName = "127.0.0.1", UserName = "guest", Password = "guest" }; //创建连接 using (IConnection connection = factory.CreateConnection()) { using (IModel channel =connection.CreateModel ()) { // Declare queue channel.QueueDeclare ( " simple " , false , false , false , null ); // Inform RabbitMQ that it will no longer distribute to the message when it has not received the message confirmation signal of the current Worker To ensure fair scheduling. channel.BasicQos (prefetchSize: 0 , prefetchCount: 1 , global : false ); // Create consumer object var consumer = new EventingBasicConsumer (channel); consumer.Received + = (model, e) => { byte [] message = e.Body.ToArray (); Console.WriteLine ( " Receive message: " + Encoding.UTF8.GetString (message)); // Return message confirmation channel.BasicAck (e.DeliveryTag, false ); }; // The consumer starts listening channel.BasicConsume ( " simple " , false , consumer); Console.ReadLine (); } } }
It can be seen that the current message reception is to send messages to any consumer who is idle (processing is completed and the message is confirmed), so the message sequence is no longer that a consumer receives singular messages, and a consumer receives even messages.