[TIMEOUT_CLEAN_QUEUE]broker busy, start flow control for a while, period in queue: 205ms, size of queue: 37
早上生产监控的告警群里看到了这么一条告警,发送消息失败。
说实话,我还是第一次遇到这个异常。简单了解了下,是broker的快速失败机制报的错。
我们用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的压力