首页 > 其他分享 >22第四章:07_消息发送重试机制

22第四章:07_消息发送重试机制

时间:2022-08-14 22:00:46浏览次数:68  
标签:发送 07 22 Broker 重试 失败 消息 Producer

一、消息发送重试机制说明

Producer 对发送失败的消息进行重新发送的机制,称为消息发送重试机制,也称为消息重投机制。

对于消息重投,需要注意以下几点:

  • 生产者在发送消息时,若采用同步或异步发送方式,发送失败会重试,但 oneway 消息发送方式发送失败是没有重试机制的
  • 只有普通消息具有发送重试机制,顺序消息是没有的
  • 消息重投机制可以保证消息尽可能发送成功、不丢失,但可能会造成消息重复。消息重复在 RocketMQ 中是无法避免的问题
  • 消息重复在一般情况下不会发生,当出现消息量大、网络抖动,消息重复就会成为大概率事件 producer 主动重发、consumer 负载变化(发生 Rebalance,不会导致消息重复,但可能出现重复消费)也会导致重复消息
  • 消息重复无法避免,但要避免消息的重复消费。
  • 避免消息重复消费的解决方案是,为消息添加唯一标识(例如消息 key),使消费者对消息进行消费判断来避免重复消费
  • 消息发送重试有三种策略可以选择:同步发送失败策略、异步发送失败策略、消息刷盘失败策略

二、同步发送失败策略

对于普通消息,消息发送默认采用 round-robin 策略来选择所发送到的队列。如果发送失败,默认重试 2 次。但在重试时是不会选择上次发送失败的 Broker,而是选择其它 Broker。当然,若只有一个 Broker 其也只能发送到该 Broker,但其会尽量发送到该 Broker 上的其它 Queue。

// 创建一个producer,参数为Producer Group名称
DefaultMQProducer producer = new DefaultMQProducer("pg");
// 指定nameServer地址
producer.setNamesrvAddr("rocketmqOS:9876");
// 设置同步发送失败时重试发送的次数,默认为2次
producer.setRetryTimesWhenSendFailed(3);
// 设置发送超时时限为5s,默认3s
producer.setSendMsgTimeout(5000);

同时,Broker 还具有失败隔离功能,使 Producer 尽量选择未发生过发送失败的 Broker 作为目标 Broker。其可以保证其它消息尽量不发送到问题 Broker,为了提升消息发送效率,降低消息发送耗时。

思考:让我们自己实现 失败隔离 功能,如何来做?

1)方案一:Producer 中维护某 JUC 的 Map 集合,其 key 是发生失败的时间戳,value 为 Broker 实例。Producer 中还维护着一个 Set 集合,其中存放着所有未发生发送异常的 Broker 实例。选择目标 Broker 是从该 Set 集合中选择的。再定义一个定时任务,定期从 Map 集合中将长期未发生发送异常的 Broker 清理出去,并添加到 Set 集合。

2)方案二:为 Producer 中的 Broker 实例添加一个标识,例如是一个 AtomicBoolean 属性。只要该 Broker 上发生过发送异常,就将其置为 true。选择目标 Broker 就是选择该属性值为 false 的 Broker。再定义一个定时任务,定期将 Broker 的该属性置为 false。

3)方案三:为 Producer 中的 Broker 实例添加一个标识,例如是一个 AtomicLong 属性。只要该 Broker 上发生过发送异常,就使其值增一。选择目标 Broker 就是选择该属性值最小的 Broker。若该值相同,采用轮询方式选择。

如果超过重试次数,则抛出异常,由 Producer 去保证消息不丢。当然当生产者出现 RemotingException、MQClientException 和 MQBrokerException 时,Producer 会自动重投消息。

三、 异步发送失败策略

异步发送失败重试时,异步重试不会选择其他 broker,仅在同一个 broker 上做重试,所以该策略无法保证消息不丢。

DefaultMQProducer producer = new DefaultMQProducer("pg");
producer.setNamesrvAddr("rocketmqOS:9876");
// 指定异步发送失败后不进行重试发送
producer.setRetryTimesWhenSendAsyncFailed(0)

四、消息刷盘失败策略

消息刷盘超时(Master 或 Slave)或 slave 不可用(slave 在做数据同步时向 master 返回状态不是 SEND_OK)时,默认是不会将消息尝试发送到其他 Broker 的。不过,对于重要消息可以通过在 Broker 的配置文件设置 retryAnotherBrokerWhenNotStoreOK 属性为 true 来开启。

标签:发送,07,22,Broker,重试,失败,消息,Producer
From: https://www.cnblogs.com/niujifei/p/16586484.html

相关文章

  • [官方 MVS(MSDN)][Windows 11 CO-21H2] 2022年7月 映像更新 - 22000.795
     简体中文-消费者版(2022年7月更新-22000.795)家庭版、家庭单语言版、教育版、专业版、专业教育版、专业工作站版(6)文件: zh-cn_windows_11_consumer_editions_......
  • 2022年谷歌Chrome等浏览器在线打开编辑保存微软Office/金山WPS的Word、Excel和PPT技术
    一、行业背景长久以来,在IE、Chrome45及Firefox53以下版本的浏览器网页中,可直接或间接调用微软免费开源的ActiveX控件DsoFramer或参考DsoFramer实现的一些收费NPAPI办公......
  • 闲话 22.8.14
    闲话意识流一把水是静止在空中的。空中的水有着别样的魔力,总能在那里流淌到终结。是的,总是终结。水并无法自己留在空中。它需要一把钥匙。钥匙总在需要的时候到来,......
  • 【2022.8.12】MySQL数据库(1)
    今日内容概要主体:数据库(入门核心)数据存取演变史数据库软件应用史数据库的本质数据库的分类MySQL数据库基本使用系统服务制作基本SQL语句今日内容详细数......
  • 剑指 Offer 07. 重建二叉树
    1.题目:输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。 示例1:  Input:pre......
  • "蔚来杯"2022牛客暑期多校训练营7
    比赛链接:https://ac.nowcoder.com/acm/contest/33192C.ConstructiveProblemsNeverDie题意:已知序列\(a\),找出一个排列\(p\)使得\(a_i!=p_i(1<=i<=n)\)。......
  • 2022河南萌新联赛第(六)场:郑州大学 (ACDFHKL)
    https://ac.nowcoder.com/acm/contest/39114C盲打(模拟)大写的时候就多个shift键就......
  • 【考试总结】2022-08-14
    生成树将曼哈顿距离中带的绝对值拆开,找到\(n\)个点中\(x+y,x-y,y-x,-x-y\)最大值对应的节点,那么其它的点必然和这四个点连边。此时形成了四个连通块,两两之间的边权大......
  • [AcWing 4507] 子数组异或和
    异或的性质点击查看代码#include<bits/stdc++.h>usingnamespacestd;typedeflonglongLL;constintN=1e6+10;intn;inta[N];voidsolve(){......
  • [冲刺国赛2022] 模拟赛15
    子串题目描述定义\(cnt(s,t)\)表示\(t\)在\(s\)中的出现次数。对于字符串\(s\),定义一个子串\(t\)是重要的,当且仅当对于任意以\(t\)为子串的\(t'\),都满足\(c......