RabbitMQ(四)——工作队列模式

前言

  工作队列模式:

    一个生产者,多个消费者,每个消费者获取到的消息唯一,当您运行多个工作线程,这些消息将在工作线程之间共享,默认轮询获取。简单的说,工作队列模式和简单模式一样,只是简单模式一个生产者一个消费者一对一,而工作队列模式一个生产者多个消费者。

                  

   这里启动三个线程,分别为生产者,消费者1,消费者2其中生产者和消费者代码与上一篇简单模式基本一致,稍作修改

实现

  生产者:

static void Main(string[] args)
        {
            //1.创建连接工厂
            ConnectionFactory factory = new ConnectionFactory()
            {
                HostName = "127.0.0.1",
                UserName = "guest",
                Password = "guest"
            };
            //2.创建连接
            var connection = factory.CreateConnection();
            //3.创建管道
            var channel = connection.CreateModel();
            //4.声明队列
            channel.QueueDeclare("simple", false, false, false, null);

            for (int i = 0; i < 20; i++)
            {
                string msg = $"第{i + 1}条消息";
                //5.发布消息
                channel.BasicPublish("", "simple", null, Encoding.UTF8.GetBytes(msg));
                Console.WriteLine($"已发送消息:{msg}");
                Thread.Sleep(1000);
            }
            channel.Close();
            connection.Close();

            Console.ReadKey();
        }
View Code

  消费者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())
                {
                    //声明队列
                    channel.QueueDeclare("simple", false, false, false, null);
                    //创建消费者对象
                    var consumer = new EventingBasicConsumer(channel);

                    consumer.Received += (model, e) =>
                    {
                        byte[] message = e.Body.ToArray();
                        Console.WriteLine("接收消息:" + Encoding.UTF8.GetString(message));
                        //返回消息确认
                        channel.BasicAck(e.DeliveryTag, false);
                    };
                    //消费者开启监听
                    channel.BasicConsume("simple", false, consumer);

                    Console.ReadLine();

                }
            }
        }
View Code

结果

  这时消费者P向队列写入消息,消费者1和消费者2会公平调度,如下:

  

 

 可以看到一个消费者接收到单数消息,另一个消费者接收到双数消息。这种情况是因为RabbitMQ在进入队列后就开始分发消息,它不会去检查每个消费者是否拥有未确认的消息数量,只是盲目的给每个消费者平均分发。

消息调度

 现在我们改变这种行为,设置BasicQos

IModel.BasicQos(0,1,false);

  

这表示让RabbitMQ不给这个消费者发送新的消息,直到消费者处理并确认了前一个消息。当消费者1的消息没确认,那么将跳过消费者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())
                {
                    //声明队列
                    channel.QueueDeclare("simple", false, false, false, null);

                    // 告知 RabbitMQ,在未收到当前 Worker 的消息确认信号时,不再分发给消息,确保公平调度。
                    channel.BasicQos(prefetchSize: 0, prefetchCount: 1, global: false);

                    //创建消费者对象
                    var consumer = new EventingBasicConsumer(channel);

                    consumer.Received += (model, e) =>
                    {
                        byte[] message = e.Body.ToArray();
                        Console.WriteLine("接收消息:" + Encoding.UTF8.GetString(message));
                        //返回消息确认
                        channel.BasicAck(e.DeliveryTag, false);
                    };
                    //消费者开启监听
                    channel.BasicConsume("simple", false, consumer);

                    Console.ReadLine();
                }
            }
        }
View Code

  

可以看到,现在的消息接收是哪个消费者空闲(处理完成并确认消息)就给哪个发送消息,所以消息顺序不再是一个消费者接收单数消息,一个消费者接收双数消息。

猜你喜欢

转载自www.cnblogs.com/zousc/p/12725636.html