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六种队列模式-主 ...
随机推荐
- Mongodb4.4安装与使用
MongoDB是一个高性能,开源,无模式的文档型数据库,是当前NoSql数据库中比较热门的一种.MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能 最丰富,最像关系数 ...
- PythonDay1Base
PythonDay1Base 变量 即python运行过程中可以发生改变的量,如同数学中的未知数X,将一个确定的量赋值给变量. 变量定义原则 由英文大小写,数字以及下划线_组成 不能以数字开头 不能以 ...
- 超详细!SED流编辑器从入门到精通
在文本处理的世界里,SED流编辑器宛如一把瑞士军刀,功能强大且实用.无论是处理海量数据文件,还是批量修改配置文件,SED都能展现出其独特的魅力.今天,就让我们一同深入探索SED的奇妙世界,掌握其基础知 ...
- JavaScript 绑定this
1.临时改变函数调用时this的指向 方法:call()与apply(),第一个参数为此次调用时的this指向,如果不传,则则等同于指定全局对象,后面的参数为函数原本的参数 区别:apply()方法传 ...
- 使用Flex布局的几个小技巧
前情 Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性,任何一个容器都可以指定为 Flex 布局,如果说目前我开发中离不开的布局方式 ...
- codeforces1849 D. Array Painting
题目链接 https://codeforces.com/problemset/problem/1849/D 题意 输入 \(n(1 \leq n \leq 2e5)\) 和长为 \(n\) 的数组 \ ...
- LeetCode题集-8 - 字符串转换整数 (atoi)
题目:请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数. 01.手动处理每个字符法 最简单的方法永远是脑海中第一个想到的方法,也是最暴力的方法,而这 ...
- LocalLLaMA 客户端试验
LM Studio. 可以直接下 hg 模型(实际使用需要自己修改成中国镜像). 有 local server, 符合 openai api 规范. 遗憾的是不支持选择显卡导致无法使用. Farada ...
- 关于 VMware 与 WSL 在 Win11 虚拟化的一些问题
关于 VMware 与 WSL 在 Win11 虚拟化的一些问题 VMware 虚拟化问题 之前用虚拟机做计网 GNS3 组网实验的时候需要用到虚拟机虚拟化,然后一直显示虚拟化不成功,检查过 BIOS ...
- 【萌狼蓝天】swagger速成
相关链接 编辑器:https://editor.swagger.io/ 文档:https://openapi.apifox.cn/ 基础信息设置 openapi: 3.0.3 info: title: ...