RabbitMQ (4)-work queue mode

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();
        }
View Code

 

  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 (); 

                } 
            } 
        }
View Code

 

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 (); 
                } 
            } 
        }
View Code

  

 

 

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.

 

 

 

 

Guess you like

Origin www.cnblogs.com/zousc/p/12725636.html