前言

经过上一篇的介绍,相信大家对RabbitMQ 的各种概念有了一定的了解,及如何使用RabbitMQ.Client 去发送和消费消息。

特性及使用场景

1. TTL 过期时间

TTL可以用来指定queue 和message多久会被去掉;在短期message数量很大,或者订单需要特定失效(例如15min支付)等场景,设置消息的过期时间可以减轻rabbitmq的压力,后者可以帮助方便的实现业务。

那么如何设置消息过期时间呢?

  • 为queue中的消息整体设置
 var ttlSetting = new Dictionary<string, Object>();
ttlSetting.Add("x-message-ttl", 10000);
queueName = _channel.QueueDeclare(arguments: ttlSetting).QueueName;
  • 为每条message设置过期时间

    var properties = _channel.CreateBasicProperties();
    properties.Expiration = "10000";
    var messageBytes = ObjectToByteArray(message);
    _channel.BasicPublish(TicketExchangeName, optType, false, properties, messageBytes);

队列TTL 设置

我们不但可以对message 设置过期时间,还可以对消息队列设置生存时间,当超过设定时间未被使用,该消息队列可以被自动删除。

设置方法同样是在声明队列的时候传入参数即可:

var ttlSetting = new Dictionary<string, Object>();
ttlSetting.Add("x-expires", 6000);
queueName = _channel.QueueDeclare(arguments: ttlSetting).QueueName;

2.  死信交换器和死信队列

何为死信?

  • 被拒绝的消息
  • 过期的消息
  • 消息队列达到最大长度

当死信发生时,死信会通过死信交换机进入到声明的死信队列,可以通过参数声明:

_channel.ExchangeDeclare(DLExchangeName, ExchangeType.Direct);
var arguments = new Dictionary<string, Object>();
arguments.Add("x-dead-letter-exchange", DLExchangeName);
_channel.QueueDeclare("dlqueue", arguments: arguments);

死信消息的路由,如果在消息初始被投送到的队列上设置了  x-dead-letter-routing-key 参数,则死信消息路由时以这个为准,否则按照它被产生时的路由key为准。例如,如果您将消息发布到具有路由密钥 foo 的交换,并且该消息是死信的,它将被发布到其具有路由密钥 foo 的死信交换。如果消息最初登陆的队列已声明为 x-dead-letter-routing-key 设置为 bar,则消息将发布到其带有路由键 bar 的死信交换。

查看死信队列中的消息可以帮助我们了解分析程序的运行健康情况,明确异常发生的原因。

3. 交换机,队列,消息的持久化

 交换机的持久化是我们在使用rabbitmq经常需要做的事情,声明交换器时将 durable 参数设置为 true 来实现的。如果不设置持久化属性的话,当 RabbitMQ 服务重启后交换器的数据就会丢失,需要注意的是,是交换器的数据丢失,消息不会丢失,只是不能将消息发送到这个交换器中了,一般生产环境使用都会把该属性设置为持久化。

队列的持久化:先介绍队列的持久化,是因为消息的持久化是依赖在队列持久化之上的。通过在声明时将durable 参数设置为 true 达到目的。

_channel.QueueDeclare(“myqueue”, true, false, arguments: ttlSetting)

消息的持久化:通过在publish 消息时,设置基本属性 DeliveryMode 来实现消息的持久性。

var properties = _channel.CreateBasicProperties();
properties.DeliveryMode = 2;

4.  消息的确认机制

相比于http请求和RPC,message queue的应用确实带来了不少便利,但引入新的application不可避免的增加了可靠性的考虑;如何确保消息从生产者准确的投递到了rabbitmq broker,又如何确保消费者真的消费了消息,又或者消费者没有重复消费消息?

这些都是我们在使用消息队列时候要考虑的问题,如何你使用何种技术(RabbitMQ或者是Kafka)。

其中,在保证消息的准确投递和消费上,RabbitMQ提供了确认机制帮助我们确保消息的可靠性。

生产端的消息确认机制:

消息确认的处理办法分为:单个消息同步确认(吞吐量低),批量消息同步确认,消息异步确认。这里只介绍异步confirm的情况。

var channel = connection.CreateModel();
channel.ConfirmSelect();
channel.BasicAcks += (sender, ea) =>
{
// code when message is confirmed
};
channel.BasicNacks += (sender, ea) =>
{
//code when message is nack-ed
};
var outstandingConfirms = new ConcurrentDictionary<ulong, string>();

如果希望在投递失败后,重新投递,可以用 ConcurrentDictionary 存储deliverTag 和 消息体,在投递失败后,重新投递。

消费端的消息确认机制:

1. 自动应答

消费者在消费消息的时候,如果设定应答模式为自动,则消费者收到消息后,消息就会立即被 RabbitMQ 从 队列中删除掉。
因此,在实际开发者,我们基本上是将消费应答模式设置为手动确认更为妥当一些。

_channel.BasicConsume(queue: queueName, autoAck: true, consumer: consumer);

2. 手动应答

消费者在收到消息后:

  • 可以在既定的正常情况下进行确认(告诉 RabbitMQ,我已经消费过该消息了,你可以删除该条数据了);
  • 可以在既定的异常情况下不进行确认(RabbitMQ 会继续保留该条数据),这样下一次可以继续消费该条数据。
_channel.BasicAck(ea.DeliveryTag, false);

本文介绍了过期时间,死信队列,应答机制和持久化的设置和使用场景,后续还会继续介绍RabbitMQ的其它特性和集群搭建,欢迎大家关注和提出意见。

---------------------------------------------------

二、RabbitMQ 进阶特性及使用场景 [.NET]的更多相关文章

  1. 重温ASP.NET WebAPI(二)进阶

    重温ASP.NET WebAPI(二)进阶   介绍 本文为个人对WebApi的回顾无参考价值. 本文内容: Rest和UnitOfWork 创建WebAPi的流程 IOC-Unity的使用 MEF ...

  2. 【算法系列学习三】[kuangbin带你飞]专题二 搜索进阶 之 A-Eight 反向bfs打表和康拓展开

    [kuangbin带你飞]专题二 搜索进阶 之 A-Eight 这是一道经典的八数码问题.首先,简单介绍一下八数码问题: 八数码问题也称为九宫问题.在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的 ...

  3. amazeui学习笔记二(进阶开发5)--Web 组件开发规范Rules

    amazeui学习笔记二(进阶开发5)--Web 组件开发规范Rules 一.总结 1.见名知意:见那些class名字知意,见函数名知意,见文件名知意 例如(HISTORY.md Web 组件更新历史 ...

  4. amazeui学习笔记二(进阶开发4)--JavaScript规范Rules

    amazeui学习笔记二(进阶开发4)--JavaScript规范Rules 一.总结 1.注释规范总原则: As short as possible(如无必要,勿增注释):尽量提高代码本身的清晰性. ...

  5. amazeui学习笔记二(进阶开发3)--HTML/CSS规范Rules

    amazeui学习笔记二(进阶开发3)--HTML/CSS规范Rules 一.总结 1.am:以 am 为命名空间 2.模块状态: {命名空间}-{模块名}-{状态描述} 3.子模块: {命名空间}- ...

  6. amazeui学习笔记二(进阶开发2)--Web组件简介Web Component

    amazeui学习笔记二(进阶开发2)--Web组件简介Web Component 一.总结 1.amaze ui:amaze ui是一个web 组件, 由模板(hbs).样式(LESS).交互(JS ...

  7. amazeui学习笔记二(进阶开发1)--项目结构structure

    amazeui学习笔记二(进阶开发1)--项目结构structure 一.总结 1.项目结构:是说的amazeui在github上面的项目结构,二次开发amazeui用 二.项目结构structure ...

  8. python函数知识七 闭包、装饰器一(入门)、装饰器二(进阶)

    21.闭包 闭包:在嵌套函数内,使用非全局变量(且不使用本层变量) 闭包的作用:1.保证数据的安全性(纯洁度).2.装饰器使用 .__closure__判断是否是闭包 def func(): a = ...

  9. Redis高级特性及应用场景

    Redis高级特性及应用场景 redis中键的生存时间(expire) redis中可以使用expire命令设置一个键的生存时间,到时间后redis会自动删除它. 过期时间可以设置为秒或者毫秒精度. ...

随机推荐

  1. [bug] flink on yarn 启动失败

    参考 https://www.cnblogs.com/huangguoming/p/11732663.html

  2. ubuntu16.04 通过命令,修改屏幕分辨率

    ubuntu16.04 通过命令,修改屏幕分辨率 l185979505 2016-10-19 08:15:54 20293 收藏 5展开第一次写博客,,,好激动,,首先通过命令: xrandr 查看可 ...

  3. 如果你想设置无人自动升级,我们推荐你将这个值修改为security,它会告诉 yum 仅仅升级修复安全问题的软件包。

    定期升级你的 CentOS 系统,是所有系统安全中最重要的措施之一.如果你不使用最新的安全补丁升级你的操作系统软件包,你将会让你的机器很容易被攻击. 如果你管理者多个 CentOS 机器,手动升级系统 ...

  4. IT菜鸟之OSI七层模型

    OSI七层模型从下到上分别是: 应用层 表示层 会话层 传输层 网络层 数据链路层 物理层 第一层物理层: 物理层是传输媒介(网线.无线.光纤) 在线路中起到的作用:是将0/1转换成电信号或光信号 物 ...

  5. DDD中实体与值对象是干什么的

    实体值对象的含义 我们前面已经讲过领域的概念, 今天来讲讲实体, 实体是我们进行设计领域模型时的基础单元, 与之有关的是值对象, 接下来先梳理一下实体以及值对象的含义,然后讲讲他们俩的关系, 希望通过 ...

  6. redis中AOF和RDB的关闭方法

    redis中AOF和RDB的关闭方法   问题:当往redis中导入数据时,有时会出现redis server went away的情况: 原因: 导入的数据量太大,而内存不够(即内存1G,但数据有2 ...

  7. Go语言的函数06---闭包函数

    package main import "fmt" /* 李逵和武松的Study方法的逻辑是几乎一模一样的 然而为了分别保存两人的学习进度,需要开辟两个全局变量,函数内部的需要使用 ...

  8. 常用深度学习框——Caffe/ TensorFlow / Keras/ PyTorch/MXNet

    常用深度学习框--Caffe/ TensorFlow / Keras/ PyTorch/MXNet 一.概述 近几年来,深度学习的研究和应用的热潮持续高涨,各种开源深度学习框架层出不穷,包括Tenso ...

  9. nvGRAPH API参考分析(二)

    nvGRAPH API参考分析(二) nvGRAPH Code Examples 本文提供了简单的示例. 1. nvGRAPH convert topology example void check( ...

  10. Python 应用领域以及版本之间的区别

    Python 应用领域以及版本之间的区别 一.Python应用领域 1. Python+人工智能,给你更多研究方向选择! 2. 企业级综合实战项目,集六大前沿技术为一体 二. Python 2与Pyt ...