文档章节

再谈 RocketMQ broker busy(实战篇)

中间件兴趣圈
 中间件兴趣圈
发布于 11/07 19:34
字数 1066
阅读 283
收藏 2

本文将在 RocketMQ 消息发送system busy、broker busy原因分析与解决方案 的基础上,结合生产上的日志尝试再次理解 broker busy 以及探讨解决方案。

首先,broker busy 相关的日志关键字如下:

  • [REJECTREQUEST]system busy
  • too many requests and system thread pool busy
  • [PC_SYNCHRONIZED]broker busy
  • [PCBUSY_CLEAN_QUEUE]broker busy
  • [TIMEOUT_CLEAN_QUEUE]broker busy

上述前面4个关键字在上篇文章中已详细介绍,本文先对出现上述错误进行一个总结,具体的分析过程请查阅上篇文章。

本文先给出一张流程图,展示上述5种 broker busy 分别会在消息发送的哪个阶段抛出,以便大家能够清晰的了解其发生的原因。 在这里插入图片描述

针对前4种 broker busy 出现的问题已经在上篇文章中详细介绍,主要是由于 Broker 在追加消息时持有的锁时间超过了设置的1s,Broker 为了自我保护,会抛出错误,客户端会选择其他 broker 服务器进行重试。如果对不是金融级服务,建议将 transientStorePoolEnable = true,可以有效避免前面 4 种 broker ,因为开启这个参数,消息首先会存储在堆外内存中,并且 RocketMQ 提供了内存锁定的功能,其追加性能能得到一定的保障,这样可以做到在内存使用层面的读写分离,即写消息是直接写入堆外内存,消费消息直接从 pagecache中读,然后定时将堆外内存的消息写入 pagecache。但这种方案随之带来的就是可能存在消息丢失,如果对消息非常严谨的话,建议扩容集群,或迁移topic到新的集群。

同时在做 Broker 服务器巡检的时候,可以通过去通过如下命令去查看 broker 一次消息追加是否会超过 500 ms。 在这里插入图片描述

在这个图中我们看到在设置了 transientStorePoolEnable 为 true 的情况下,虽然一天只有一条超过500ms的消息,但也值得警惕了,由于对系统内核参数掌握程度不够,这种情况,估计只能走集群扩容的路子了。但如果一天消息量巨大而且出现频率不高的情况,由于有重试机制,倒不会带来太大的问题。如果出现太多的错误,建议集群扩容

本文接下来想重点探讨一下 [TIMEOUT_CLEAN_QUEUE]broker busy 这种情况。

BrokerFastFailure#cleanExpiredRequest

while (true) {
    try {
        if (!this.brokerController.getSendThreadPoolQueue().isEmpty()) {
            final Runnable runnable = this.brokerController.getSendThreadPoolQueue().peek();
            if (null == runnable) {
                break;
            }
            final RequestTask rt = castRunnable(runnable);
            if (rt == null || rt.isStopRun()) {
                break;
            }

            final long behind = System.currentTimeMillis() - rt.getCreateTimestamp();
            if (behind >= this.brokerController.getBrokerConfig().getWaitTimeMillsInSendQueue()) {
                if (this.brokerController.getSendThreadPoolQueue().remove(runnable)) {
                    rt.setStopRun(true);
                    rt.returnResponse(RemotingSysResponseCode.SYSTEM_BUSY, String.format("[TIMEOUT_CLEAN_QUEUE]broker busy, start flow control for a while, period in queue: %sms, size of queue: %d", behind, this.brokerController.getSendThreadPoolQueue().size()));
                }
            } else {
                break;
            }
        } else {
            break;
        }
    } catch (Throwable ignored) {
    }
}

可以看出来,抛出这种错误,在 broker 还没有发送“严重”的 pagecache 繁忙,即消息追加到内存中的最大时延没有超过 1s,通常追加是很快的,绝大部分都会低于1ms,但可能会由于出现一个超过200ms的追加时间,导致排队中的任务等待时间超过了200ms,则此时会触发broker 端的快速失败,让请求快速失败,便于客户端快速重试。但是这种请求并不是实时的,而是每隔10s 检查一遍。

值得注意的是,一旦出现 TIMEOUT_CLEAN_QUEUE,可能在一个点会有多个这样的错误信息,具体多少与当前积压在待发送队列中的个数有关。

关于 [TIMEOUT_CLEAN_QUEUE]broker busy 我们也可以适当调整 waitTimeMillsInSendQueue,默认值为200ms,可以适当调整到400ms。

如果大家觉得文章对您有帮助的话,麻烦帮忙点个赞,谢谢。


> 作者介绍:《RocketMQ技术内幕》作者,维护公众号:中间件兴趣圈,目前主要发表了源码阅读java集合、JUC(java并发包)、Netty、ElasticJob、Mycat、Dubbo、RocketMQ、mybaits等系列源码。

© 著作权归作者所有

中间件兴趣圈

中间件兴趣圈

粉丝 26
博文 23
码字总数 62086
作品 0
青浦
私信 提问
RocketMQ 平滑升级到主从切换实战

本文主要介绍如何将 RocketMQ 集群从原先的主从同步升级到主从切换。 首先介绍与 DLedger 多副本即 RocketMQ 主从切换相关的核心配置属性,然后尝试搭建一个主从同步集群,再从原先的 Rocket...

丁威
10/13
0
0
《RocketMQ技术内幕:RocketMQ架构设计与实现原理》一导读

内容介绍 本书由RocketMQ社区早期的布道者和技术专家撰写,Apache RocketMQ创始人/Linux OpenMessaging创始人兼主席/Alibaba Messaging开源技术负责人冯嘉对其高度评价并作序推荐。 源码角度...

小编辑01
01/04
0
0
消息中间件 RocketMQ 源码解析 —— 调试环境搭建

摘要: 原创出处 www.iocoder.cn/RocketMQ/bu… 「芋道源码」欢迎转载,保留摘要,谢谢! 0. 友情提示 1. 依赖工具 2. 源码拉取 3. 启动 RocketMQ Namesrv 4. 启动 RocketMQ Broker 5. 启动 ...

芋道源码_以德服人_不服就干
01/31
0
0
RocketMQ(八):消息发送

匠心零度 转载请注明原创出处,谢谢! RocketMQ网络部署图 NameServer:在系统中是做命名服务,更新和发现 broker服务。 Broker-Master:broker 消息主机服务器。 Broker-Slave: broker 消息...

匠心零度
2018/10/29
0
0
说说MQ之RocketMQ(一)

原文出处:Valleylord RocketMQ 是出自 A 公司的开源产品,用 Java 语言实现,在设计时参考了 Kafka,并做出了自己的一些改进,消息可靠性上比 Kafka 更好,目前,RocketMQ 的文档仍然不够丰...

Valleylord
2018/10/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Kafka实战(五) - 核心API及适用场景全面解析

1 四个核心API ● Producer API 允许一个应用程序发布一串流式的数据到一个或者多个Kafka topic。 ● Consumer API 允许一个应用程序订阅一个或多个topic ,并且对发布给他们的流式数据进行处...

JavaEdge
21分钟前
5
0
实现线程的第三种方式——Callable & Future

Callable Runnable 封装一个异步运行的任务, 可以把它想象成为一个没有参数和返回值的异步方 法。Callable 与 Runnable 类似, 但是有返回值。Callable 接口是一个参数化的类型, 只有一 个...

ytuan996
今天
8
0
OSChina 周六乱弹 —— 不要摁F了!

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @巴拉迪维 : 朴树写的词曲都给人一种莫名的失落感,不过这首歌他自己却没有唱,换成赵传这种高音阶嘶喊的确很好,低沉但却有力,老男人的呐喊...

小小编辑
今天
10
0
Android Binder机制 - interface_cast和asBinder讲解

研究Android底层代码时,尤其是Binder跨进程通信时,经常会发现interface_cast和asBinder,很容易被这两个函数绕晕,下面来讲解一下: interface_cast 下面根据下述ICameraClient例子进行分析...

天王盖地虎626
昨天
12
0
计算机实现原理专题--存储器的实现(二)

计算机实现原理专题--存储器的实现(一)中描述了一种可以记住输入端变化的装置。现需要对其功能进行扩充,我们将上面的开关定义为置位,下面的开关定义为复位,然后需要增加一个保持位,当保...

FAT_mt
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部