RabbitMQ(四)——工作队列模式
RabbitMQ系列
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();
}
消费者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(); }
}
}
结果
这时消费者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();
}
}
}

可以看到,现在的消息接收是哪个消费者空闲(处理完成并确认消息)就给哪个发送消息,所以消息顺序不再是一个消费者接收单数消息,一个消费者接收双数消息。
附上Demo地址:https://github.com/1164887865/RabbitMQDemo
RabbitMQ(四)——工作队列模式的更多相关文章
- RabbitMq四种模式介绍和授权
rabbitmqctl change_password admin admin123 修改admin密码 界面管理和授权操作 1新增用户 rabbitmqctl add_user admin amin ...
- RabbitMQ (四) 工作队列之公平分发
上篇文章讲的轮询分发 : 1个队列,无论多少个消费者,无论消费者处理消息的耗时长短,大家消费的数量都一样. 而公平分发,又叫 : 能者多劳,顾名思义,处理得越快,消费得越多. 生产者 public c ...
- RabbitMQ六种队列模式-工作队列模式
前言 RabbitMQ六种队列模式-简单队列RabbitMQ六种队列模式-工作队列 [本文]RabbitMQ六种队列模式-发布订阅RabbitMQ六种队列模式-路由模式RabbitMQ六种队列模式-主 ...
- 【RabbitMQ学习之二】RabbitMQ四种交换机模式应用
环境 win7 rabbitmq-server-3.7.17 Erlang 22.1 一.概念1.队列队列用于临时存储消息和转发消息.队列类型有两种,即时队列和延时队列. 即时队列:队列中的消息会被立 ...
- 深入学习RabbitMQ(四):channel的confirm模式
转自:http://m.blog.csdn.net/article/details?id=54340711 上一篇博客我们介绍了使用RabbitMQ可能会遇到的一个问题,即生产者不知道消息是否真正到达 ...
- RabbitMQ六种队列模式-简单队列模式
前言 RabbitMQ六种队列模式-简单队列 [本文]RabbitMQ六种队列模式-工作队列RabbitMQ六种队列模式-发布订阅RabbitMQ六种队列模式-路由模式RabbitMQ六种队列模式-主 ...
- 【RabbitMQ】工作模式介绍
一.前言 之前,笔者写过< CentOS 7.2 安装 RabbitMQ> 这篇文章,今天整理一下 RabbitMQ 相关的笔记便于以后复习. 二.模式介绍 在 RabbitMQ 官网上提 ...
- RabbitMQ(四):RPC的实现
原文:RabbitMQ(四):RPC的实现 一.RPC RPC(Remote Procedure Call)—远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议. ...
- RabbitMQ六种队列模式-发布订阅模式
前言 RabbitMQ六种队列模式-简单队列RabbitMQ六种队列模式-工作队列RabbitMQ六种队列模式-发布订阅 [本文]RabbitMQ六种队列模式-路由模式RabbitMQ六种队列模式-主 ...
- RabbitMQ六种队列模式-路由模式
前言 RabbitMQ六种队列模式-简单队列RabbitMQ六种队列模式-工作队列RabbitMQ六种队列模式-发布订阅RabbitMQ六种队列模式-路由模式 [本文]RabbitMQ六种队列模式-主 ...
随机推荐
- Elasticsearch之基本使用
这里大概解答下各个目录.配置文件的作用: 目录 配置文件 描述 bin 放置脚本文件,如启动脚本 elasticsearch, 插件安装脚本等. config elasticserch.yml e ...
- js 实现可缓存方法
1.概述 有些场景下,如果一些函数需要大量的运算,但是他们的传入的参数是一样的,这个时候,我们可以将这些运算缓存下来,之后的运算就可以不用重复计算了. 2.实现方法 <script> // ...
- uniapp 画布
1.前言 uniapp中的canvas与HTML中的canvas用法并不同,他的使用文档请参考微信小程序画布 2.基本使用 1.准备canvas容器,并为其设置canvas-id和宽高(为了兼容H5, ...
- 【Amadeus原创】修改docker里面网站的port端口映射
切记:以下顺序千万不能颠倒!否则不生效! 1. 查看需要修改的容器,记住container id docker ps -a 2. 停止容器 docker stop xxx 3. 修改容器的端口映射配置 ...
- mysql restart
bin/mysqld --defaults-file=/etc/mysql.cnf --user=mysql bin/mysqld --user=app --basedir=/opt/mysql-5. ...
- 【转载】Netty堆外内存泄漏排查
https://www.imooc.com/article/298943 上篇文章介绍了Netty内存模型原理,由于Netty在使用不当会导致堆外内存泄漏,网上关于这方面的资料比较少,所以写下这篇文章 ...
- Qt开发经验小技巧241-245
QString类是我个人认为Qt所有类中的精华,封装的无可挑剔.内置了各种进制数据的转换,比如将数据转成10进制.16进制显示,或者将10进制.16进制数据转成字符串显示.这里很容易忽略的一点就是,很 ...
- asp.net mvc中换肤机制类库 ThemedViewEngines
制作blog系统或者通用cms系统的时候,我们经常会用到Theme功能.asp.net mvc中的一种实现方式,是继承实现RazorViewEngine即可. 这是在GitHub中找到的一个示例:ht ...
- Java实现任务管理器性能网络监控数据
在现代操作系统中,任务管理器是一个非常重要的工具,用于监控和管理计算机的运行状态,包括CPU使用率.内存占用.磁盘I/O以及网络流量等.对于开发者和系统管理员来说,了解这些性能数据有助于优化应用程序和 ...
- cpa-税法
1.税法总论 2.增值税法 3.消费税法 4.企业所得税法 5.个人所得税法 6.城市维护建设税法和烟叶税法 7.关税法和船舶吨税法 8.资源税法和环境保护税法 9.城镇土地使用税法和耕地占用税法 1 ...