这里是weihubeats,觉得文章不错可以关注公众号小奏技术,文章首发。拒绝营销号,拒绝标题党
RocketMQ版本
- 5.1.0
背景
最近线上的RocketMQ
集群遇到了如下问题,业务方的小伙伴反馈问题,说出现了
MQBrokerException:CODE:2DESC:[TIMEOUT_CLEAN_QUEUE]broker busy,start flow control for a while,period in queue
相关的错误导致发送消息失败。自信看过源码的我马上回复了别怕会重试
结果业务方的小伙伴马上回复说重试好像也没有成功,被啪啪打脸
带着这个疑问我又去查看了源码
消息发送失败重试
啪很快的就找到了DefaultMQProducerImpl
这个类,然后找到了sendDefaultImpl
这个发送消息的实现类
并在此找到了重试的关键代码
if (this.defaultMQProducer.getRetryResponseCodes().contains(e.getResponseCode()))
可以看到这里只有是this.defaultMQProducer.getRetryResponseCodes()
方法里面的code才会重试,我们看看具体哪些cde
ResponseCode.TOPIC_NOT_EXIST,
ResponseCode.SERVICE_NOT_AVAILABLE,
ResponseCode.SYSTEM_ERROR,
ResponseCode.NO_PERMISSION,
ResponseCode.NO_BUYER_ID,
ResponseCode.NOT_IN_CURRENT_UNIT
看着挺正常的,那咋没重试呢
broker快速失败
知道了哪些错误才会重试就好解决问题了,我们去看看我broker
快速失败返回的是什么状态码
public static final int SYSTEM_BUSY = 2;
重试没有这个code
会是bug吗
心想可能是RocketMQ
的bug?所以去社区看了下
实际这个问题早在社区有过很多的讨论,而且有相关pr
地址:
https://github.com/apache/rocketmq/pull/5845
其中RocketMQ
的维护者大致的意思是 broker都已经非常忙了,你还要重试干嘛,让他歇息会不行吗?
但是实际的情况是如此吗?
线上我们会是多主架构,一个master broker压力大,另一个并不一定的
但是还有一个很神奇的问题,为啥商业版本就支持SYSTEM_BUSY
的重试呢?
你这不是明显坑我们开源用户吗?那最终社区又做了一个妥协。
我们就是设计这里不支持重试,您非要重试就自己添加配置
所以就有了一个可以支持用手手动配置重试code
的PR
配置重试code
这个PR
目前已经被merge了相关的链接
https://github.com/apache/rocketmq/pull/2729
如果我们要支持SYSTEM_BUSY
的重试可以做如下配置
DefaultMQProducer producer = new DefaultMQProducer(PRODUCER_GROUP);
producer.setNamesrvAddr(DEFAULT_NAMESRVADDR);
producer.addRetryResponseCode(RemotingSysResponseCode.SYSTEM_BUSY);
问题圆满解决了?
问题圆满解决了吗?显然我们仅仅是解决了一个表面问题,我们还需要正对broker
出现SYSTEM_BUSY
做优化,具体如何优化那是下篇文章的事,关这篇文章什么事呢哈哈
好啦,今天的RocketMQ
故事分享就到这了,我是weihubeats
,觉得文章不错可以微信关注小奏技术