Rabbitmq 消息保存机制

mandatory参数和immediate参数作用

  1. mandatory:当参数设置为true时,交换器无法根据自身的类型和路由键找到一个符合条件的队列,Rabbitmq会把消息返回给生产者
  2. immediate:当参数设置为true时,如果交换器在将消息路由到队列时发现队列上并不存在任何消费者,那么这条消息将不会存入队列中,当与路由键匹配的所有队列都没有消费者都没有消费者时,该消息会被返回给发送者。

immediate 3.0版本后不支持,可以使用TTL和DLX方法代替。

备份交换机

生产者在发送消息的时候如果不设置mandatory参数,那么消息在未被路由的情况下将被丢失,如果设置了该参数,则发送者需要增加ReturnListener机制,使得发送者代码变得复杂,此时,可以使用备份交换机使得未被路由的消息存储到Rabbitmq中,需要的时候再去处理这些消息。

设置myAe作为normalExchange备份交换机,并设置绑定类型为fanout,则当消息发送到normalExchange并且找不到合适的路由队列时会将消息发送到备份交换机:

如果备份交换机和mandatory参数一起使用,mandatory参数不生效

Rabbitmq TTL 消息过期时间

设置消息过期时间的两种方式:

  1. 通过队列属性设置,队列中所有消息都有相同的过期时间(消息过期则会被从队列中抹去,因为已过期的消息在队列头部,定期扫描即可)
  2. 对消息本身进行单独设置,每条消息的TTL可以不同,如果两种一起使用,以TTL小的为准(不会立即抹去,而是在投递时进行判断)。
    消息在队列中的生存时间超过设置的TTL值时,就会变成死信,消费者将无法再收到该消息

如果不设置TTL,则表示此消息不会过期,如果设置为0,除非立即将消息投递到消费者,否则该消息将被丢弃。

Rabbitmq DLX 私信队列

概念:DLX全称为死信队列,当消息在一个队列中成为私信之后,它能被重新发送到另一个交换其中,这交换器就是DLX,绑定DLX的队列就称为死信队列。
触发时机:一般由于以下几种情况

  1. 消息被拒绝(Basic.Reject/Basic.Nack),并且设置requeue为false。
  2. 消息过期
  3. 队列达到最大长度。

补充:
Basic.Reject: 消费端告诉Rabbitmq拒绝处理,如果requeue为true则重新投递到消息队列
Basic.Nack:批量拒绝,拒绝时传递deliveryTag(消息编号),拒绝时拒绝掉所有未被当前消费者确认(ACK)的消息。

DLX也是一个正常的交换器,和一般的交换器没有区别,能被绑定到任何队列上,当这个队列存在私信时,rabbitmq就会自动将这个消息重新发布到设置的DLX上去,进而路由到私信队列,可以通过消费者订阅死信队列,进而进行逻辑处理。这个特性与TTL设置为0配合使用,可以替代immediate参数的功能。

示例如下:
原理图:

Rabbitmq 延迟队列

Rabbitmq不支持延迟队列,但可以通过TTL和DLX机制实现延迟队列功能。
步骤:

  1. 生产者发送消息到normalExchange,进而路由到normalQueue中,消息过期时间设置5,10,30min…,消费者并非订阅该队列
  2. 为normalExchange配置死信队列,当消息过期时,从normalQueue路由到DLXQueue,消费者订阅DLXQueue,进而实现消息延时消费。
    原理图:

Rabbitmq 优先级队列

步骤:

  1. 为队列设置最大优先级10
  2. 发送消息时指定消息的优先级
  3. 优先级高的先被消费,最低优先级为0
  4. 当消费者消费速度大于生产者生产速度,优先级队列将毫无意义。

Rabbitmq 持久化

持久化层级:

  1. 交换器的持久化
  2. 队列的持久化
  3. 消息的持久化

交换器的持久化

通过在声明交换器时将durable设为true,如果没有设置持久化,rabbitmq重启后,相关的交换器元数据会丢失,但消息不会丢失,只是生产者无法再将消息发送到这个交换器中。

队列的持久化

声明队列时将durable设为true,如果队列不设置持久化,那么rabbitmq重启后,相关队列的元数据会丢失,此时数据也会丢失。队列持久化,可以保证本身的元数据不会丢失,但无法保证内部的消息不会丢失。

消息的持久化

消息的持久化可以保证消息不会丢失,通过将消息的投递模式deliveryMode设为2实现消息的持久化。

当设置了队列持久化和消息的持久化,当Rabbitmq服务重启,消息依旧存在,单单设置队列持久化,重启之后消息会丢失,只设置消息的持久化,重启队列之后,队列会丢失进而消息也会丢失。

注意:
可以将所有消息都设置为持久化,但是会严重影响Rabbitmq性能,写入磁盘速度远远小于写入内存。因此,在选择持久化时,需要在可靠性和吞吐量之间做一个权衡。

Rabbitmq消息 可靠性保证

消息持久化保证

设置了交换器,队列,消息持久化机制后,仍无法保证消息不会丢失。因为在持久化的消息存入磁盘之中仍需要一段时间,因为Rabbitmq不会为每条消息进行同步刷盘(调用内核的fsync),可能仅仅将消息保存到操作系统的缓存中,而不是物理磁盘,如果此时Rabbitmq服务器宕机,消息会丢失。
解决方案:

引入Rabbitmq镜像队列,相当于配置了副本,此时master宕机,仍然可以自动切换到从节点。

生产者确认

消息发送出去,可能未正确到达Rabbitmq服务器。
解决方案:

  1. 通过事务机制实现
  2. 通过发送方确认机制实现。
通过事务机制

调用txSelect将当前通道设置成事务模式,此时便可以将消息发送到rabbitmq,调用txCommit提交事务如果提交成功则消息一定到达了Rabbitmq,如果出现异常则可以调用txRollback将事务回滚。

整个提交流程中客户端和服务端增加了四个步骤

  1. tx.select将信道设为事务模式
  2. Broker回复selectOk,确认信道已设为事务模式
  3. tx.commit提交事务
  4. Broker回复commitOk,确认事务提交。
    因此,使用事务机制会极大程度影响Rabbitmq的性能。
发送方确认

生产者将信道设置为confirm模式,一旦信道进入confirm模式,所有在该信道上发布的消息都会被指派一个唯一的id,一旦消息被投递到所有匹配的队列之后,Rabbitmq就会发送一个确认(Basc.Ack)给生产者,这就使得生产者知道消息已经正确到达目的地,如果消息和队列是可持久化的,则消息会被写入磁盘后再发送ACK。此外,如果设置basicAck中的multiple参数为true,则表示序号之前的消息都已经得到了处理。
事务机制在发送完一条消息之后,就会使得发送端阻塞,之后才能继续发送下一条消息,相比之下,发送方确认机制最大好处是一步的,一旦发送一条消息,生产者就可以在等待信道返回确认的同时继续发送下一条消息,如果Rabbitmq内部错误则会返回一条NACK,发送到注册回调监听nack即可。

批量confirm

批量confirm模式中,客户端程序需要定期或者定量的调用channel.waitForConfirms来等待Rabbitmq确认返回,问题在于出现返回Basic.Nack或者超时情况时,客户端需要将这个批次的消息全部重发,会带来消息的重复消息数量,并且在经常发生消息丢失时,批量confirm性能反而会下降。

异步confirm

Rabbitmq消息保存机制应用案例分析消息可靠性保证相关推荐

  1. Netty消息接收类故障案例分析

    <Netty 进阶之路>.<分布式服务框架原理与实践>作者李林锋深入剖析Netty消息接收类故障案例.李林锋此后还将在 InfoQ 上开设 Netty 专题持续出稿,感兴趣的同 ...

  2. VC++/MFC消息映射机制(1):MFC消息映射原理

    VC++/MFC消息映射机制(1):模仿MFC的消息映射原理 本文为原创文章,转载请注明出处,或注明转载自"黄邦勇帅(原名:黄勇) <C++语法详解>网盘地址:https://p ...

  3. rocketmq 消息指定_RocketMq 实际案例–普通消息的发送

    RocketMq 实际案例–普通消息的发送 @(消息中间件)[RocketMq 实例] 学习 rocketMq 最根本的是要先学会用嘛,在创建 rocketMq 的第一个案例的时候,碰到很多坑,可以记 ...

  4. RabbitMQ消息确认机制

    文章目录 1. 事务机制 2. Confirm模式 2.1 生产者 2.1.1 普通Confirm模式 2.1.2 批量Confirm模式 2.1.3 异步Confirm模式 2.2 消费者 3. 其 ...

  5. kafka 消息分发机制、分区和副本机制

    一.消息分发机制 1.1 kafka 消息分发策略 消息是 kafka 中最基本的数据单元,在 kafka 中,一条消息由key.value两部分构成,在发送一条消息 时,我们可以指定这个key,那么 ...

  6. 1553B总线消息刷新机制

    一.BC工作机制 总线控制器通讯软件是整个系统正常工作的基础, 主要负责系统 B C端信息的实时传输, 包括命令字的发送. 数据字的收发及状态字的接收. 通信表和总线表是系统运行的依据, 它们都是由一 ...

  7. RocketMQ-顺序消息Demo及实现原理分析

    文章目录 场景分析 全局顺序消费 局部顺序消费 Demo Producer Demo Normal Consumer Demo Order Consumer Demo 源码分析 锁定MessageQu ...

  8. 什么是消息补偿机制?

    为什么还要消息补偿机制呢? 难道消息还会丢失,没错,系统是在一个复杂的环境,不要想的太简单了,虽然以上的三种方案,基本可以保证消息的高可用不丢失的问题,但是作为有追求的程序员来讲,要绝对保证我的系统的 ...

  9. iOS-动态方法决议与消息转发机制

    在消息发送机制中我们介绍过,OC是动态语言,对象调用方法其实就是对象接收消息,而消息的发送采用"动态绑定"机制,具体会调用哪个方法直到运行时才确定,然后去执行绑定的代码. 绑定的过 ...

最新文章

  1. 【SpringMVC】基本概念
  2. Eclipse+Maven创建web项目
  3. 综述 | 三大路径,一文总览知识图谱融合预训练模型的研究进展
  4. 王茂霖:数据挖掘提分三板斧!(附PPT下载)
  5. 王贻芳院士:我们的科技管理过度强调竞争,缺乏稳定支持
  6. qpython手机版-QPython,一个在手机上运行Python的神器
  7. CDN简介及linux环境下搭建
  8. 如何加快Vivado的编译速度
  9. C#面向对象设计模式第九讲:Composite 组合模式(结构型模式)
  10. 笔试题 - 阶乘问题
  11. Protocol Buffer技术详解(C++实例)
  12. Java 多线程 —— 常用并发容器
  13. oracle 序列_Oracle好记性不如烂笔头序列及日期时间的插入
  14. html当前行突出显示,Pandas Dataframes to_html:突出显示表行
  15. 设置多行的Table高度为100%,并在最后一行中加入iframe
  16. *C#(WPF)--矩阵拖动和矩阵动画(拖动展开,不足动画效果)
  17. java 调用tomcat api,tomcat处理http请求-下
  18. 大数据面试3分钟自我介绍_面试的时候,如何自我介绍?
  19. SpringBoot 发送邮件和附件(实用版)
  20. html canvas 烟花 特效代码

热门文章

  1. linux cdn服务器,wdcdn系统,CDN缓存系统,CDN加速系统,多节点CDN自架系统,CDN安装配置部署--Linux解决方案,技术支持与培训,服务器架构,性能优化,负载均衡,集群分流...
  2. 计算机技能节大赛广播稿,技能大赛获奖感言
  3. 写一份入职优秀员工的获奖感言,真诚一点,大约3分钟
  4. HDU - 奔小康赚大钱(二分图最佳匹配+KM)
  5. 使用Python实现基于强化学习与游戏化学习典型算法
  6. 木姐说副业:新手小白利用业余时间搞兼职,操作健身项目赚钱,轻松实现财务自由
  7. mysql char,mysql to_char
  8. 大伯走了,永远的走了!
  9. 关于智能车_电磁三轮pid控制的学习过程
  10. http无状态协议如何保存用户状态