.Net RabbitMQ实战指南——进阶(一)
备份交换器
备份交换器,英文名称为Alternate Exchange,简称AE。通过在声明交换器(调用channel.ExchangeDeclare方法)时添加alternate-exchange参数来实现。
备份交换器工作流程如下:

using (var channel = connection.CreateModel())
{
//设置备胎交换器参数
var arguments = new Dictionary<string, object>();
arguments.Add("alternate-exchange","myAe");
channel.ExchangeDeclare("normalExchange", "direct",true,false, arguments);
channel.ExchangeDeclare("myAe", "fanout", true, false);
channel.QueueDeclare("nromalQueue",true,false,false);
channel.QueueBind("nromalQueue", "normalExchange", "normalKey");
channel.QueueDeclare("unroutedQueue", true, false, false);
channel.QueueBind("unroutedQueue", "myAe","ae"); var properties = channel.CreateBasicProperties();
properties.DeliveryMode = 2;
string message = "RabbitMQ Test"; //传递的消息内容
channel.BasicPublish("normalExchange", "normalKey", properties, Encoding.UTF8.GetBytes(message)); //生产消息
channel.BasicPublish("normalExchange", "un-routkey", properties, Encoding.UTF8.GetBytes(message)); //生产消息 Console.WriteLine($"Send:{message}");
}
代码中声明了两个交换器normalExchange和myAe,分别绑定了normalQueue和unroutedQueue这两个队列,同时将myAe设置为normalExchange的备份交换器。myAe的交换器类型为fanout。同时生成两条消息,其中“un-routkey”并没有定义对应路由。
运行效果:

切换到queues视图,可以看到两个队列分别有一条需要消费的消息。

备份交换器与普通的交换器没有太大的区别,为了方便使用,建议设置为fanout类型
过期时间(TTL)
TTL,Time to Live的简称,即过期时间。RabbitMQ可以对队列和消息设置TTL。
设置队列的TTL
channel.QueueDeclare方法中的x-expires参数可以设置队列被自动删除前处于未使用状态的时间。未使用是指队列上没有任何的消费者,队列也没有被重新声明过,并且其间内也未调用过Basic.Get命令。
var arguments = new Dictionary<string, object>();
arguments.Add("x-expires", 10000); //单位毫秒
channel.QueueDeclare(arguments: arguments);
RabbitMQ重启后,持久化的队列的过期时间会被重新计算。
设置消息的TTL
消息的过期时间有两种设置方式。第一种是通过队列属性设置,队列中所有消息都有相同的过期时间。第二种方法是对消息本身进行设置。
如果两种方法一起使用,则消息的TTL以两者之间较小的那个数值为准。消息在队列中的生存时间一旦超过设置的TTL值,就会变成“死信”(Dead Message)
通过队列属性设置消息TTL的方法是在channel.QueueDeclare方法中加入x-message-ttl参数实现的,这个参数的单位是毫秒。
arguments.Add("x-message-ttl", 6000); //单位毫秒
channel.QueueDeclare(arguments: arguments);
对消息本身进行过期时间设置前面代码有涉及过,是通过BasicPublish方法的basicProperties参数指定。
var properties = channel.CreateBasicProperties();
properties.DeliveryMode = 1;
properties.Priority = 2;
properties.Expiration = "6000";
var message = "RabbitMQ Test"; //传递的消息内容
channel.BasicPublish("", "stacking", properties, Encoding.UTF8.GetBytes(message)); //生产消息
死信队列
DLX,全称为Dead-Letter-Exchange,即死信交换器。当一个消息在队列中变成死信(dead message),它就会被重新被发送到DLX(死信交换器),绑定DLX的队列就称之为死信队列。
通过在channel.QueueDeclare方法中设置x-dead-letter-exchange参数来为这个队列添加DLX.
示例代码:
var arguments = new Dictionary<string, object>();
arguments.Add("x-expires", 10000); //单位毫秒
arguments.Add("x-message-ttl", 6000); //单位毫秒
channel.QueueDeclare(arguments: arguments); channel.ExchangeDeclare("dlx_exchange", "direct");
var argumentsDlx = new Dictionary<string, object>();
argumentsDlx.Add("x-dead-letter-exchange", "dlx_exchange");
argumentsDlx.Add("x-dead-letter-routing-key", "dlx-routing-key"); //为DLX指定路由键,如果没有特殊指定,则使用原队列的路由键
channel.QueueDeclare("dlx_queue",false,false,false,argumentsDlx);
可以看到dlx_queue有标记了DLX和DLK(Dead-Letter-Key)。

DLX是一个非常有用的特性。异常情况下,消息不能够被消费者正确消费(消费者调用了Basic.Nack或者Basic.Reject)而被置入死信队列中,后续分析程序可以通过死信队列中的内容来分析当时所遇到的异常情况,从而改善和优化系统。
延迟队列
延迟队列存储的是对应的延迟消息,“延迟消息”并不想让消费者立刻消息,而是等待特定时间后,消费者才能拿到这个消息进行消费。如一个订单系统中,用户下单30分钟内没有完成支付那么就对该订单进行异常处理,就可以使用延迟队列来处理这些订单。
RabbitMQ并支持延迟队列的功能,但是我们可以通过DLX和TTL模拟出延迟队列的功能。如下图所示:

实例中设置了5秒、10秒、30秒、1分钟四个延时等级。根据应用需求的不同,生产者在发送消息的时候设置不同的路由键,从而将消息发送到与交换器绑定的对应队列中。这些队列分别设置了过期时间为5秒、10秒、30秒、1分钟,同时也分别配置了DLX和相应的死信队列。队列中消息过期时,就会转存到相应的死信队列(即延迟队列)中,在根据业务自身的情况,分别选择不同延迟等级的延迟队列进行消费。
优先级队列
优先级队列,有高优先级的队列具有高的优先权,优先级高的消息有优先被消费的特权。
可以通过设置队列的x-max-priority参数来实现。并在发送消息时通过Priority设置消息优先级。
using (var channel = connection.CreateModel())
{ channel.ExchangeDeclare("priority_exchange", "direct");
var arguments = new Dictionary<string, object>();
arguments.Add("x-max-priority", 10); //
channel.QueueDeclare("priority_queue", false, false, false, arguments);
channel.QueueBind("priority_queue", "priority_exchange", "priority_key"); var properties = channel.CreateBasicProperties();
properties.Priority = 2;
string message = "Priority 2"; //传递的消息内容
channel.BasicPublish("priority_exchange", "priority_key", properties, Encoding.UTF8.GetBytes(message)); //生产消息
properties.Priority = 5;
message = "Priority 5"; //传递的消息内容
channel.BasicPublish("priority_exchange", "priority_key", properties, Encoding.UTF8.GetBytes(message)); //生产消息
var result = channel.BasicGet("priority_queue", false);
channel.BasicAck(result.DeliveryTag, true);
Console.WriteLine($"Received:{Encoding.UTF8.GetString(result.Body.ToArray())}"); }
运行上面的代码,不管我们如何调整生成消息的顺序,channel.BasicGet取出来的始终是Priority为5的那条消息。

Github
示例代码地址:https://github.com/MayueCif/RabbitMQ
.Net RabbitMQ实战指南——进阶(一)的更多相关文章
- .Net RabbitMQ实战指南——进阶(二)
持久化 持久化可以提高RabbitMQ的可靠性,防止异常情况下的数据丢失.RabbitMQ的持久化分为三个部分:交换器的持久化.队列的持久化和消息的持久化. 交换器的持久化通过声明队列时将durabl ...
- 【RabbitMQ 实战指南】一 RabbitMQ 开发
1.RabbitMQ 安装 RabbitMQ 的安装可以参考官方文档:https://www.rabbitmq.com/download.html 2.管理页面 rabbitmq-management ...
- 【RabbitMQ 实战指南】一 延迟队列
1.什么是延迟队列 延迟队列中存储延迟消息,延迟消息是指当消息被发送到队列中不会立即消费,而是等待一段时间后再消费该消息. 延迟队列很多应用场景,一个典型的应用场景是订单未支付超时取消,用户下单之后3 ...
- 【RabbitMQ 实战指南】一 死信队列
1.死信队列 DLX,全称为 Dead-Letter-Exchange,可以称之为死信交换器.当消息在一个队列中变成死信(dead message)之后,它能被发送到另一个交换器中,这个交换器就是DL ...
- 【RabbitMQ 实战指南】一 过期时间TTL
RabbitMQ 可以对消息和队列设置过期时间(TTL) 1.设置消息的TTL 目前有两种方式可以设置消息的TTL 第一种方式是通过队列属性设置,队列中所有消息都有相同的过期时间 第二种方式是对消息本 ...
- 【RabbitMQ 实战指南】一 RabbitMQ入门
1.消息中间件 1.1.什么是消息中间件 消息中间件(Message Queue Middleware,简称 MQ)是指利用高效可靠的消息传递机制进行与平台无关的数据交流,并基于数据通道来进行分布式系 ...
- .Net RabbitMQ实战指南——客户端开发
开发中关键的Class和Interface有Channel.Connection.ConnectionFactory.Consumer等,与RabbitMQ相关的开发工作,基本上是围绕Connecti ...
- .Net RabbitMQ实战指南——RabbitMQ相关概念介绍
什么是消息中间件 消息(Message)是指在应用间传送的数据.消息可以非常简单,比如只包含文本字符串.JSON等,也可以很复杂,比如内嵌对象. 消息队列中间件(Message Queue Middl ...
- .Net RabbitMQ实战指南——HTTP API接口调用
RabbitMQ Management插件还提供了基于RESTful风格的HTTP API接口来方便调用.一共涉及4种HTTP方法:GET.PUT.DELETE和POST.GET方法一般用来获取如集群 ...
随机推荐
- 路由协议之RIP
目录 RIP协议 RIP的路由汇总和过滤 RIP的认证 RIP的防环机制 华为/思科中的配置 RIP协议 RIP协议是一种内部网关协议(IGP),底层是贝尔曼福特算法,是一种动态路由选择协议,用于自治 ...
- Java Web中间件
目录 中间件 常见的web中间件有哪些 Tomcat Weblogic Jboss Jetty Webshere Glasshfish 中间件 我们经常会看到中间件,但是,一直好奇的是,中间件到底是什 ...
- Win64 驱动内核编程-22.SHADOW SSDT HOOK(宋孖健)
SHADOW SSDT HOOK HOOK 和 UNHOOK SHADOW SSDT 跟之前的 HOOK/UNHOOK SSDT 类似,区别是查找SSSDT的特征码,以及根据索引计算函数地址的公式,还 ...
- Day003 巧妙验证短路运算
&&的短路运算 条件1&&条件2...&&条件n,程序会先判断条件1,如果条件1为false,则不判断后面的条件,直接返回false 怎么判断程序到底有 ...
- Catalan数以及相关性质的证明
\(Catalan\) 数相关证明 Mushroom 2021-5-14 \(Catalan\)数的定义 给定一个凸\(n + 1\)边形, 通过在内部不相交的对角线,把它划分成为三角形的组合,不同的 ...
- NtQuerySystemInformation获取进程/线程状态
__kernel_entry NTSTATUS NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS SystemInformationClass, P ...
- Windows反调试技术(上)
写在前面 在逆向工程中为了防止破解者调试软件,通常都会在软件中采用一些反调试技术来防破解.下面就是一些在逆向工程中常见的反调试技巧与示例. BeingDebuged 利用调试器加载程序时调试器会通过C ...
- (四)Jira Api对接:缺陷分析和任务分析
迭代进行期间或者结束后,在我们的测试日报或者测试报告中需要体现缺陷详细情况,甚至大家工作效率情况.本文就讨论下如何通过jira api获取缺陷信息并进行分析,同时获取需求子任务情况来了解测试和开发的工 ...
- OO随笔之魔鬼的第一单元——多项式求导
OO是个借助Java交我们面向对象的课,可是萌新们总是喜欢带着面向过程的脑子去写求导,然后就是各种一面(main)到底.各种方法杂糅,然后就是被hack的很惨. 第一次作业:萌新入门面向对象 题目分析 ...
- 3D高清电商购物小图标图片_在线商城三维icon图标素材大全
3D高清电商购物小图标图片_在线商城三维icon图标素材大全