【RocketMQ中生产者生产消息的高可用机制、消费者消费消息的高可用机制、消息的重试机制、死信队列于死信消息】

一.知识回顾

【0.RocketMQ专栏的内容在这里哟,帮你整理好了,更多内容持续更新中】
【1.Docker安装部署RocketMQ消息中间件详细教程】
【2.RocketMQ生产者发送消息的三种方式:发送同步消息、异步消息、单向消息&案例实战&详细学习流程】
【3.RocketMQ消费者进行消费消息的二种方式:集群消费、广播消费&案例实战&详细学习流程&集群消费模、广播模式的适用场景&注意事项】
【4.RocketMQ中的顺序消息、生产者顺序生产消息、消费者顺序消费消息、顺序包括全局有序和分块有序、代码样例实战】
【5.RocketMQ中延时消息的生产与消费、批量消息的生产与消费、消息的过滤、消息的Tag过滤和SQL过滤、SQL过滤解决SQL92问题,代码样例实战】
【6.RocketMQ分布式事务消息、RocketMQ分布式事务的发展流程、RocketMQ分布式事务二阶段提交解决方案、分布式案例实操学习、RocketMQ分布式事务使用场景以及注意事项】
【7.一文带你详细学习RocketMQ存储设计方案、RocketMQ中消息文件存储结构、过期文件删除机制、零拷贝与MMAP内存映射】
【8.RocketMQ的高可用原理机制、RocketMQ的集群部署方式、数据刷盘机制中的同步刷盘和异步刷盘、主从同步机制和主从异步机制、broker文件中的相关配置信息以及代表的含义】

二.RocketMQ中生产者生产消息的高可用机制

2.1 消息生产的高可用机制

在这里插入图片描述

  1. 在创建Topic的时候,把Topic的多个Message Queue创建在多个Broker组上,当一个Broker组的Master不可用后,其他组的Master仍然可用,Producer仍然可以发送消息。
  2. RocketMQ目前不支持把Slave自动转成Master,如果机器资源不足, 需要把Slave转成Master,则要手动停止Slave角色的Broker,更改配置文件,用新的配置文件启动Broker。

2.2 高可用消息的生产流程

在这里插入图片描述

  1. TopicA创建在双主中,BrokerA和BrokerB中,每一个Broker中有4个队列
  2. 选择队列默认是使用轮训的方式,比如发送一条消息A时,选择BrokerA中的四个队列中的其中一个
  3. 如果发送成功,消息A发结束。
  4. 如果消息发送失败,默认会采用重试机制
retryTimesWhenSendFailed	同步模式下内部尝试发送消息的最大次数  默认值是2
retryTimesWhenSendAsyncFailed	异步模式下内部尝试发送消息的最大次数 默认值是2
  1. 如果发生了消息发送失败,这里有一个规避策略(默认配置):
  • (1) 默认不启用Broker故障延迟机制(规避策略):如果是BrokerA宕机,上一次路由选择的是BrokerA中的Q4,那么再次重发的队列选择是BrokerA中的Q1。但是这里的问题就是消息发送很大可能再次失败,引发再次重复失败,带来不必要的性能损耗。

  • (2) 注意,这里的规避仅仅只针对消息重试,例如在一次消息发送过程中如果遇到消息发送失败,规避 broekr-a,但是在下一次消息发送时,即再次调用 DefaultMQProducer 的 send 方法发送消息时,还是会选择 broker-a 的消息进行发送,只有继续发送失败后,重试时再次规避 broker-a。

    为什么会默认这么设计?
    1、某一时间段,从NameServer中读到的路由中包含了不可用的主机
    2、不正常的路由信息也是只是一个短暂的时间而已。
    生产者每隔30s更新一次路由信息,而NameServer认为broker不可用需要经过120s。
    在这里插入图片描述

  • (3). 启用Broker故障延迟机制:代码如下

    producer.setNameSrvAddr("localhost:9876");
    producer.start();
    //启动Broker故障延迟机制
    producer.setSendLatencyFaultEnable(true);
    
    1. 开启延迟规避机制,一旦消息发送失败(不是重试的)会将 Broker-a “悲观”地认为在接下来的一段时间内该 Broker 不可用,在未来某一段时间内所有的客户端不会向该 Broker 发送消息。这个延迟时间就是通过 notAvailableDuration、latencyMax 共同计算的,就首先先计算本次消息发送失败所耗的时延,然后对应 latencyMax 中哪个区间,即计算在 latencyMax 的下标,然后返回 notAvailableDuration 同一个下标对应的延迟值。
      (涉及算法,后面我们学习的时候讲解)
    2. 在发送失败后,在接下来的固定时间(比如5分钟)内,发生错误的BrokeA中的队列将不再参加队列负载,发送时只选择BrokerB服务器上的队列。
    3. 如果所有的 Broker 都触发了故障规避,并且 Broker 只是瞬间压力大,那岂不是明明存在可用的 Broker,但经过你这样规避,反倒是没有 Broker 可用来,那岂不是更糟糕了。所以RocketMQ默认不启用Broker故障延迟机制

三.RocketMQ中消费者消费消息的高可用机制

3.1 主从的高可用原理

  1. 在Consumer的配置文件中,并不需要设置是从Master读还是从Slave 读,当Master不可用或者繁忙的时候,Consumer会被自动切换到从Slave 读。有了自动切换Consumer这种机制,当一个Master角色的机器出现故障后,Consumer仍然可以从Slave读取消息,不影响Consumer程序。这就达到了消费端的高可用性。
  2. Master不可用这个很容易理解,那什么是Master繁忙呢?
    这个繁忙其实是RocketMQ服务器的内存不够导致的。当前需要拉取的消息已经超过常驻内存的大小,表示主服务器繁忙,此时才建议从从服务器拉取。

3.2 消息的重试机制

3.2.1 消息消费的重试
  1. 消费端如果发生消息失败,没有提交成功,消息默认情况下会进入重试队列中。

  2. 注意重试队列的名字其实是跟消费群组有关,不是主题,因为一个主题可以有多个群组消费。

3.2.2 顺序消息的重试
  1. 对于顺序消息,当消费者消费消息失败后,消息队列 RocketMQ 会自动不断进行消息重试(每次间隔时间为 1 秒),这时,应用会出现消息消费被阻塞的情况。因此,在使用顺序消息时,务必保证应用能够及时监控并处理消费失败的情况,避免阻塞现象的发生。
  2. 当我们使用顺序消息时,需要注意consume消费消息失败时,不能返回reconsume—later,这样会导致乱序,应该返回suspend_current_queue_a_moment,意思是先等一会,一会儿再处理这批消息,而不是放到重试队列里。
3.2.3 无序消息的重试
  1. 对于无序消息(普通、定时、延时、事务消息),当消费者消费消息失败时,可以通过设置返回状态达到消息重试的结果。
  2. 无序消息的重试只针对集群消费方式生效;广播方式不提供失败重试特性,即消费失败后,失败消息不再重试,继续消费新的消息。
3.2.4 重试次数
第几次重试与上次重试的间隔时间第几次重试与上次重试的间隔时间
110 秒97 分钟
230 秒108 分钟
31 分钟119 分钟
42 分钟1210 分钟
53 分钟1320 分钟
64 分钟1430 分钟
75 分钟151 小时
86 分钟162 小时

注意:

  1. 如果消息重试 16 次后仍然失败,消息将不再投递。如果严格按照上述重试时间间隔计算,某条消息在一直消费失败的前提下,将会在接下来的 4 小时 46 分钟之内进行 16 次重试,超过这个时间范围消息将不再重试投递。
  2. 一条消息无论重试多少次,这些重试消息的 Message ID 不会改变。
3.2.5 重试配置

集群消费方式下,消息消费失败后期望消息重试,需要在消息监听器接口的实现中明确进行配置(三种方式任选一种):

  1. 返回 RECONSUME_LATER (推荐)
  2. 返回 Null
  3. 抛出异常

集群消费方式下,消息失败后期望消息不重试,需要捕获消费逻辑中可能抛出的异常,最终返回CONSUME_SUCCESS,此后这条消息将不会再重试。

3.2.6 自定义消息最大重试次数

消息队列 RocketMQ 允许 Consumer 启动的时候设置最大重试次数,重试时间间隔将按照如下策略:

  1. 最大重试次数小于等于 16 次,则重试时间间隔同上表描述。
  2. 最大重试次数大于 16 次,超过 16 次的重试时间间隔均为每次 2 小时。
consumer.setMaxReconsumeTimes(20);

注意:
1.消息最大重试次数的设置对相同 Group ID 下的所有 Consumer 实例有效。
2.如果只对相同 Group ID下两个 Consumer 实例中的其中一个设置MaxReconsumeTimes,那么该配置对两个 Consumer 实例均生效。
3.配置采用覆盖的方式生效,即最后启动的 Consumer 实例会覆盖之前的启动实例的配置。

3.3 死信队列

3.3.1 死信队列的概念

当一条消息初次消费失败,消息队列 RocketMQ 会自动进行消息重试;达到最大重试次数后,若消费依然失败,则表明消费者在正常情况下无法正确地消费该消息,此时,消息队列 RocketMQ 不会立刻将消息丢弃,而是将其发送到该消费者对应的特殊队列中。
在消息队列 RocketMQ 中,这种正常情况下无法被消费的消息称为死信消息(Dead-Letter Message),存储死信消息的特殊队列称为死信队列(Dead-Letter Queue)。

3.3.2 死信消息的特性
  1. 不会再被消费者正常消费。
  2. 有效期与正常消息相同,均为 3 天,3 天后会被自动删除。因此,请在死信消息产生后的 3 天内及时处理。
3.3.3 死信队列的特性
  1. 不会再被消费者正常消费。
  2. 一个死信队列对应一个 Group ID, 而不是对应单个消费者实例。
  3. 如果一个 Group ID 未产生死信消息,消息队列 RocketMQ 不会为其创建相应的死信队列。
  4. 一个死信队列包含了对应 Group ID 产生的所有死信消息,不论该消息属于哪个 Topic。
3.3.4 查看死信消息
  1. 在控制台查询出现死信队列的主题信息,在消息界面根据主题查询死信消息,可以选择重新发送消息
  2. 一条消息进入死信队列,意味着某些因素导致消费者无法正常消费该消息,因此,通常需要您对其进行特殊处理。排查可疑因素并解决问题后,可以在消息队列 RocketMQ 控制台重新发送该消息,让消费者重新消费一次。

好了,到这里【RocketMQ中生产者生产消息的高可用机制、消费者消费消息的高可用机制、消息的重试机制、死信队列于死信消息】就先学习到这里,关于RocketMQ的内容持续更新创作中。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

硕风和炜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值