RabbitMQ系列

RabbitMQ(一)——简介

RabbitMQ(二)——模式类型

RabbitMQ(三)——简单模式

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

RabbitMQ(五)——发布订阅模式

RabbitMQ(六)——路由模式

RabbitMQ(七)——主题模式

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(四)——工作队列模式的更多相关文章

  1. RabbitMq四种模式介绍和授权

    rabbitmqctl change_password admin admin123 修改admin密码 界面管理和授权操作 1新增用户 rabbitmqctl add_user admin amin ...

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

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

  3. RabbitMQ六种队列模式-工作队列模式

    前言 RabbitMQ六种队列模式-简单队列RabbitMQ六种队列模式-工作队列 [本文]RabbitMQ六种队列模式-发布订阅RabbitMQ六种队列模式-路由模式RabbitMQ六种队列模式-主 ...

  4. 【RabbitMQ学习之二】RabbitMQ四种交换机模式应用

    环境 win7 rabbitmq-server-3.7.17 Erlang 22.1 一.概念1.队列队列用于临时存储消息和转发消息.队列类型有两种,即时队列和延时队列. 即时队列:队列中的消息会被立 ...

  5. 深入学习RabbitMQ(四):channel的confirm模式

    转自:http://m.blog.csdn.net/article/details?id=54340711 上一篇博客我们介绍了使用RabbitMQ可能会遇到的一个问题,即生产者不知道消息是否真正到达 ...

  6. RabbitMQ六种队列模式-简单队列模式

    前言 RabbitMQ六种队列模式-简单队列 [本文]RabbitMQ六种队列模式-工作队列RabbitMQ六种队列模式-发布订阅RabbitMQ六种队列模式-路由模式RabbitMQ六种队列模式-主 ...

  7. 【RabbitMQ】工作模式介绍

    一.前言 之前,笔者写过< CentOS 7.2 安装 RabbitMQ> 这篇文章,今天整理一下 RabbitMQ 相关的笔记便于以后复习. 二.模式介绍 在 RabbitMQ 官网上提 ...

  8. RabbitMQ(四):RPC的实现

    原文:RabbitMQ(四):RPC的实现 一.RPC RPC(Remote Procedure Call)—远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议. ...

  9. RabbitMQ六种队列模式-发布订阅模式

    前言 RabbitMQ六种队列模式-简单队列RabbitMQ六种队列模式-工作队列RabbitMQ六种队列模式-发布订阅 [本文]RabbitMQ六种队列模式-路由模式RabbitMQ六种队列模式-主 ...

  10. RabbitMQ六种队列模式-路由模式

    前言 RabbitMQ六种队列模式-简单队列RabbitMQ六种队列模式-工作队列RabbitMQ六种队列模式-发布订阅RabbitMQ六种队列模式-路由模式 [本文]RabbitMQ六种队列模式-主 ...

随机推荐

  1. 【FAQ】HarmonyOS SDK 闭源开放能力 —Push Kit(6)

    1.问题描述: 推送通知到手机,怎么配置拉起应用指定的页面? 解决方案: 1.如果点击通知栏打开默认Ability的话, actionType可以设置为0, 同时可以在.clickAction.dat ...

  2. base64计算文件大小方法(C#和js)

    base64文件大小计算 有时候图片被base64之后需要计算图片大小,因为被编码后全是字符,计算文件大小可以反序列化成文件之后再获取大小,但是会比较麻烦.简单介绍一种利用base64编码原理计算大小 ...

  3. Visual Studio 使用IISprofile进行远程部署

      ​

  4. Postman无法启动

    前情 最近在捣鼓node.js,需要一个接口测试工具,而Postman是业界有名的接口测试工具,自然接口测试就用它了. 坑 已经有一段时间没启动Postman了,突然发现启动一直卡在修复界面,重启也不 ...

  5. R数据分析:跨层中介的原理和做法,实例操练

    之前有同学问过我211模型,没听过这个词,感觉怎么有这么不严肃的名字,偷偷去查了查,211模型,其实就是嵌套数据的中介的情形之一.根本上讲还是属于多水平模型的路径分析(用多水平模型跑回归也可以做中介, ...

  6. 2000 Star,是时候为我的开源项目更新下功能了

    哈喽啊,我是阿朗,马上就要年末了,已经半年多没有更新文章了.年初定的计划早已经忘的一干二净.再不捡起来一点东西,就要2025年了. 要写点东西了. 你是一个博客撰写专家,你擅长开发领域,你喜欢使用通俗 ...

  7. 解锁 Git Log 更多实用技巧

    目前,在软件开发的协作中,Git 无疑是版本控制的王者. 而其中的 git log 命令,犹如一把强大的历史探寻之剑,能够帮助我们深入洞察项目的演进历程. 本篇将为大家整理解读几个实用的 git Lo ...

  8. Ubuntu中文件夹建立软链接方法

    1:预备知识 -s 是代号(symbolic)的意思. 这里有两点要注意:第一,ln命令会保持每一处链接文件的同步性,也就是说,不论你改动了哪一处,其它的文件都会发生相同的变化:第二,ln的链接又软链 ...

  9. Could not retrieve transation read-only status server 的解决办法

    问题描述: 在项目开发的过程中,使用Hibernate的ORM进行建表时,出现 " Could not retrieve transation read-only status server ...

  10. 【转】ReentrantReadWriteLock读写锁详解

    https://www.cnblogs.com/xiaoxi/p/9140541.html 一.读写锁简介 现实中有这样一种场景:对共享资源有读和写的操作,且写操作没有读操作那么频繁.在没有写操作的时 ...