技术:rocketmq 4.9.1 + rocketmq spring starter 2.2.1
demo功能:分享一个由rocketmq spring starter bug引起的消费堆积处理
上文已经彻底分析了问题的来龙去脉,这次接着分析周边问题。如果你没有看过上文,建议先看,否则不好理解。
6. 周边问题解决
第二个问题:在消费详情中,为什么Pull消费者在Dashboard中不显示消费者client和queue的关系信息呢?
实际下图的空白中,是Pull消费者消费的,却没有consumerClient。
第三个问题:在消费者实例列表中,明明Pull和Push消费者的ConsumerType不一样,为什么这里只显示了CONSUME_ACTIVELY(Pull)
下面先解释第二个问题。
用户看到的消费详情是怎么来的呢?调用代码逻辑是由上至下查看的,依次是
rocketmq-dashboard --->
rocketmq admin tool --->
rocketmq broker --->
rocketmq client。
逻辑我从下上到上解释下,主要分为几步:
消费者client启动时,通过立即发送心跳将自身信息上报给broker。
broker保存消费者信息。
dashboard通过admin tool的接口获取消费者信息展示。
通过以上简单描述后我们知道:我们看到的信息都是消费者自己上报的结果,哪些信息有,哪些信息没有,就只需要看哪些信息消费者是否有上报逻辑即可。
这里贴下主要代码截图:
dashboard代码
实际在调试中发现,
1. Pull消费者连接信息在Broker中正常上报保存。也即是
ConsumerConnection对象正常返回。
2. Pull消费者在根据client id获取ConsumerRunningInfo信息时,返回空。
通过getConsumerRunningInfo()方法,我们顺藤摸瓜,发现是broker在接到getConsumerRunningInfo()调用时,它调用了client的接口获取当前运行时信息。
Broker代码
这里broker调用了client的接口,实时获取了ConsumerRunningInfo信息。
Client上报消费者代码
消费者客户端在收到broker的请求后,客户端通过
最终调用到了consumerRunningInfo()方法。
这个方法在DefaultLitePullConsumer、DefaultMQPullConsumer、DefaultMQPushConsumer的一些响应实现有不一样。
当前问题RocketMQ Spring Starter使用的是DefaultLitePullConsumer,以下我截图了关键不同代码:左边是DefaultLitePullConsumer,右边是DefaultMQPushConsumer的实现逻辑:
可以看出DefaultLitePullConsumer没有上报自己消费了哪些queue,所以在dashboard中看不到。
现在我们解释下第三个问题。
其实是Broker存储消费的问题,消费者信息是如何到broker中的,代码调用次序如:
rocketmq client 消费者 --->
心跳 ---->
broker --->
ConsumerManager#registerConsumer()--->
ConsumerManager. consumerTable.
通过以上代码,我们可以知道:相同消费者组名的ConsumeType,MessageModel,ConsumeFromWhere都只有一个值,谁先上报在dashboard的消费者实例列表中就看到谁的。
至此,大部分问题已经解释清楚,长文感谢大家阅读。
继续思考:
1. 如果使用阿里云配置了namespace,还会发生有意思的现象。核心逻辑在client组将namespace和topic,消费者的时候。
2. 第三个问题,只是发现了问题,怎么彻底处理呢?理论上所有的消费者dashboard都应该看到,并且consumerType也应该正确。
文末推荐
笔者编写的《RocketMQ分布式消息中间件(核心原理与最佳实践)》最近jd618活动半价,欢迎大家阅读
欢迎添加微信,互相学习↑↑↑ -_-
白老虎
programming is not only to solve problems, ways to think
grafana 级连 菜单 templating (variables) 配置
rocketmq 集群搭建 (2master + 2slave + 2namesrv)
AI 机器人 抓取 微信 聊天中的 百度网盘 分享地址和密码