mq超时异常org.apache.rocketmq.client.exception.MQBrokerException: CODE: 2 DESC: [TIMEOUT_CLEAN_QUEUE]broker busy, start flow control for a while, period in queue: 203ms, size of queue: 1

     mq生产环境正常生产和消费都挺稳定的,99.999%应该都没问题的,比较稳定。今天刚好碰到过一例因为写超时导致异常问题。

    

    2023-02-23 21:19:58.449 TID:8b8a430ff3d34213a374de3550822503.789.16771583982424385 [ERROR] [NettyClientPublicExecutor_2] [c.g.m.m.p.m.UserTaskOraProducer:90] --- UserTaskOraProducer发送失败,key:task_post_be_highlightU910943377267384320,typeCode:task_post_be_highlight
+1

21:19:59.018
2023-02-23 21:19:58.449 TID:8b8a430ff3d34213a374de3550822503.727.16771583977572409 [WARN ] [XNIO-1 task-43] [RocketmqClient:130] --- sendKernelImpl exception, resend at once, InvokeID: 4921002808992973274, RT: 204ms, Broker: MessageQueue [topic=marketing-badge-task-gray, brokerName=RaftNode00, queueId=1]
+2

21:19:59.018
org.apache.rocketmq.client.exception.MQBrokerException: CODE: 2  DESC: [TIMEOUT_CLEAN_QUEUE]broker busy, start flow control for a while, period in queue: 203ms, size of queue: 1
+3

21:19:59.018
For more information, please visit the url, http://rocketmq.apache.org/docs/faq/
+4

21:19:59.018
    at org.apache.rocketmq.client.impl.MQClientAPIImpl.processSendResponse(MQClientAPIImpl.java:665)
+5

21:19:59.018
    at org.apache.rocketmq.client.impl.MQClientAPIImpl.sendMessageSync(MQClientAPIImpl.java:505)
+6

21:19:59.018
    at org.apache.rocketmq.client.impl.MQClientAPIImpl.sendMessage$original$gcDrtLSO(MQClientAPIImpl.java:487)
+7

21:19:59.018
    at org.apache.rocketmq.client.impl.MQClientAPIImpl.sendMessage$original$gcDrtLSO$accessor$n9m8eZyq(MQClientAPIImpl.java)
+8

21:19:59.018
    at org.apache.rocketmq.client.impl.MQClientAPIImpl$auxiliary$uyI9DykF.call(Unknown Source)
+9

21:19:59.018
    at org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstMethodsInter.intercept(InstMethodsInter.java:86)
+10

21:19:59.018
    at org.apache.rocketmq.client.impl.MQClientAPIImpl.sendMessage(MQClientAPIImpl.java)

 

 

我们用rocketMQ发消息的流程,大致就是首先producer向broker发送消息写入请求,broker接收到请求之后会放进队列中(这个队列大小默认10000),然后有一个线程数为1的线程来从队列取消息去执行消息写入。

正常这个流程没啥,但是一旦broker端挤压了大量的请求而得不到及时的处理。消息发送端默认的超时时间是3s,这样数据量大的时候就大概率会出现不少超时的情况,这些就会造成大量的无效处理。

所以rocketMQ就引入了快速失败机制,简单来说就是开了个定时任务,默认是将队列中超过200ms的请求直接取消,直接向客户端返回失败。

很多人认为都去github上去提了issue,认为SYSTEM_ERROR类型的错误,broker端都做了重试,为啥 SYSTEM_BUSY遗漏了,觉得这是一个bug。

但是作者的回复是,当broker繁忙的时候,自动重试无疑只会增加mq的压力,起不到关键的帮助。

解决方案:
将 waitTimeMillsInSendQueue 调大,默认是200ms
开启 transientStorePoolEnable
扩容
简单讲一下第二种,开启 transientStorePoolEnable 的方式

 

transientStorePoolEnable置为true之后,相当于消息直接写入到堆外内存,然后消息一批批写入到pageCache,以此来降低对pageCache的压力
————————————————
版权声明:本文为CSDN博主「白衣神棍」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_29914229/article/details/126831516

posted @ 2023-02-27 11:11  Doyourself!  阅读(1709)  评论(0编辑  收藏  举报