上一篇讲了简单队列,实际工作中,这种队列应该很少用到,因为生产者发送消息的耗时一般都很短,但是消费者收到消息后,往往伴随着对高消息的业务逻辑处理,是个耗时的过程,这势必会导致大量的消息积压在一个消费者手中,从而导致业务的积压.

所以我们需要多个消费者一起消费队列中的消息,模型如下:(为了方便讲解,暂时隐藏掉"交换机")

生产者

    public class Producer
{
private const string QueueName = "test_work_queue";
public static void Send()
{
//获取一个连接
using (IConnection connection = ConnectionHelper.GetConnection())
{
//从连接中获取一个信道
using (IModel channel = connection.CreateModel())
{
//声明队列
channel.QueueDeclare(QueueName, false, false, false, null); for (int i = ; i < ; i++)
{
//创建消息
string msg = "hello world " + i;
//发送消息
channel.BasicPublish("", QueueName, null, Encoding.Default.GetBytes(msg));
Console.WriteLine($"{DateTime.Now} : send {msg}");
}
}
}
}
}

消费者1

    public class Consumer1
{
private const string QueueName = "test_work_queue";
public static void Receive()
{
//获取一个连接
IConnection connection = ConnectionHelper.GetConnection(); //从连接中获取一个信道
IModel channel = connection.CreateModel(); //声明队列
channel.QueueDeclare(QueueName, false, false, false, null); //添加消费者
EventingBasicConsumer consumer = new EventingBasicConsumer(channel); //注册消费者收消息事件
consumer.Received += (s, e) =>
{
byte[] bytes = e.Body;
string str = Encoding.Default.GetString(bytes);
Console.WriteLine("consumer1 receive : " + str);
Thread.Sleep();//休息0.5秒
}; //开启消费者监听
channel.BasicConsume(QueueName, true, "", false, false, null, consumer);
}
}

消费者2

只有一点点区别:

                Console.WriteLine("consumer2 receive : " + str);
Thread.Sleep();//休息1秒

我们这里故意让两个消费者处理消息的耗时不一样,一个0.5秒,一个1秒.

我们来看看结果:

可以非常清楚的看到,尽管两个消费者处理消息的"耗时"不一样,但是处理的"数量"是一样的.

这里有几个细节要说明一下:

1.在生产者和两个消费者中都声明了同一个队列.其实,如果这个队列之前已经存在了,那么生产者和消费者都可以不用再声明了;

2.一定要先启动两个消费者,再启动生产者.原因是,我们上面的代码中,消费者的 BasicConsume 方法的第2个参数传入的是 true,

这个参数就是 autoAck :是否自动确认(上面文章有讲过).

所以如果先开启生产者,那么会瞬间发送完50条消息,这时候启动消费者1,那么会立刻"消费"掉这50条消息.有朋友肯定要问,不是"睡"了0.5秒么?

这里"睡"0.5秒,是对消息的业务逻辑处理耗时,而不是"消费"消息,消息已经在消费者启动的那一刻从队列中"拿"过来了;

同时,由于采用的是"自动确认",所以队列看到50条都被"确认"了,就会将这些消息从队列中移除.

这时候再启动消费者2,则不会收到任何消息.

RabbitMQ (三) 工作队列之轮询分发的更多相关文章

  1. RabbitMQ学习第二记:工作队列的两种分发方式,轮询分发(Round-robin)和 公平分发(Fair dispatch)

    1.什么是RabbitMQ工作队列 我们在应用程序使用消息系统时,一般情况下生产者往队列里插入数据时速度是比较快的,但是消费者消费数据往往涉及到一些业务逻辑处理导致速度跟不上生产者生产数据.因此如果一 ...

  2. RabbitMQ基本示例,轮询机制,no_ack作用

    一.RabbitMQ简介: ''' RabbitMQ就是消息队列 之前不是学了Queue了吗,都是队列还学RabbitMQ干嘛? 干的事情是一样的 Python的Queue有两个, 一个线程Queue ...

  3. demo rabbitmq topic(主题模式),fanout(广播模式),轮询分发,确认接收Ack处理

    //durable = true 代表持久化 交换机和队列都要为true ,持久代表服务重启,没有处理的消息依然存在 //topic 根据不同的routkey 发送和接收信息 //fanout 广播模 ...

  4. RabbitMQ的轮询模式和公平分发

    一.常用的消息模式 我们在工作的使用中,经常会遇到多个消费者监听同一个队列的情况,模型如下图所示: 当有多个消费者时,我们的消息会被哪个消费者消费呢,我们又该如何均衡消费者消费信息的多少呢: 主要有两 ...

  5. RabbitMQ (四) 工作队列之公平分发

    上篇文章讲的轮询分发 : 1个队列,无论多少个消费者,无论消费者处理消息的耗时长短,大家消费的数量都一样. 而公平分发,又叫 : 能者多劳,顾名思义,处理得越快,消费得越多. 生产者 public c ...

  6. php和ajax 服务器端做轮询推送(定义)

    基于HTTP的长连接,是一种通过长轮询方式实现"服务器推"的技术,它弥补了HTTP简单的请求应答模式的不足,极大地增强了程序的实时性和交互性. 一.什么是长连接.长轮询? 用通俗易 ...

  7. Web 通信 之 长连接、长轮询(转)

    Web 通信 之 长连接.长轮询(long polling) 基于HTTP的长连接,是一种通过长轮询方式实现"服务器推"的技术,它弥补了HTTP简单的请求应答模式的不足,极大地增强 ...

  8. Web 通信 之 长连接、长轮询(long polling)

    基于HTTP的长连接,是一种通过长轮询方式实现"服务器推"的技术,它弥补了HTTP简单的请求应答模式的不足,极大地增强了程序的实时性和交互性. 一.什么是长连接.长轮询? 用通俗易 ...

  9. nginx负载均衡 加权轮询和ip_hash

    下面给大家总结了几种真正的nginx负载均衡的功能了,在此我们加了一个权重判断法就是根据nginx负载的状态实现分配访问用户到权重值少的机器了,具体配置如下. nginx为后端web服务器(apach ...

随机推荐

  1. [Leetcode] Multiply strings 字符串对应数字相乘

    Given two numbers represented as strings, return multiplication of the numbers as a string. Note: Th ...

  2. 【BZOJ 2432】 [Noi2011]兔农 矩乘+数论

    这道题的暴力分还是很良心嘛~~~~~ 直接刚的话我发现本蒟蒻只会暴力,矩乘根本写不出来,然后让我们找一下规律,我们发现如果我们把这个序列在mod k的意义下摆出,并且在此过程中把值为1的的数减一,我们 ...

  3. HTTP请求中同步与异步有什么不同

    普通的B/S模式就是同步,而AJAX技术就是异步,当然XMLHttpReques有同步的选项. 同步:提交请求->等待服务器处理->处理完毕返回.这个期间客户端浏览器不能干任何事. 异步: ...

  4. Clevo P950系列拆机

    Clevo P950系列(包括神舟精盾T96/T97/T96C/T96E/T97E,炫龙耀9000,铁头人T800同模具机型)拆机 拆机恢复时间:20181203 12:28-14:58   一.普通 ...

  5. E. Intercity Travelling

    E. Intercity Travelling time limit per test 1.5 seconds memory limit per test 256 megabytes input st ...

  6. 牛客 国庆七天乐 day1 L

    https://www.nowcoder.com/acm/contest/201/L 题意:给你两条平行的直线和n个圆,在直线上面行走和在圆上和在圆内行走不需要耗费体力,除了这些区域外平面上经过任意两 ...

  7. Firefox多国语言多OS离线安装包

    Download Firefox in your language Firefox is made in large part by volunteers around the world. That ...

  8. ORACLE中根据生日得到年龄

    create or replace function F_GETAGE(dateofbirth date) return varchar2 is begin ) then ); else ) then ...

  9. LOJ tangjz的背包

    题目大意 有 \(n\) 个物品, 第 \(i\) 个物品的体积为 \(i\) 令 \(f(x)\) 为 选择 \(m\) 个物品, 体积和为 \(x\) 的方案数 令 \(V = \sum_{i=1 ...

  10. Python基础(5)_文件操作

    一.文件处理流程 打开文件,得到文件句柄并赋值给一个变量 通过句柄对文件进行操作 关闭文件 二.文件打开模式 打开文件时,需要指定文件路径和以何等方式打开文件,打开后,即可获取该文件句柄,日后通过此文 ...