RocketMQ 主题扩分片后遇到的坑

fileReservedTime = 48

brokerRole = ASYNC_MASTER

flushDiskType = ASYNC_FLUSH

brokerIP1=192.168.0.220

brokerIP2-192.168.0.220

namesrvAddr=192.168.0.221:9876;192.168.0.220:9876

storePathRootDir=/opt/application/rocketmq-all-4.5.2-bin-release/store

storePathCommitLog=/opt/application/rocketmq-all-4.5.2-bin-release/store/commitlog

autoCreateTopicEnable=false

autoCreateSubscriptionGroup=false

备注:公司对 topic、消费组进行了严格的管控,项目组需要使用时需要向运维人员申请,故 broker 集群不允许自动创建主题与自动创建消费组。

由于该业务量稳步提升,项目组觉得该主题的队列数太少,不利于增加消费者来提高其消费能力,故向运维人员提出增加队列的需求。

1.2、RocketMQ 在线扩容队列

运维通过公司自研的消息运维平台,直接以指定集群的方式为 topic 扩容,该运维平台底层其实使用了RocketMQ 提供的 updateTopic 命令,其命令说明如下:

图片来源于《》RocketMQ技术内幕》

从上图可以得知可以通过 -c 命令来指定在集群中所有的 broker 上创建队列,在本例中,将队列数从 4 设置为 8,具体命令如下:

sh ./mqadmin upateTopic -n 192.168.0.220:9876 -c DefaultCluster -t topic_dw_test_by_order_01 -r 8 -w 8

执行效果如图所示,表示更新成功。

在这里插入图片描述

我们再来从 rocketmq-console 中来看命令执行后的效果:

在这里插入图片描述

从上图可以得知,主题的队列数已经扩容到了8个,并且在集群的两台broker上都创建了队列。

1.3 消息发送

从 RocketMQ 系列可知,RocketMQ 是支持在线 topic 在线扩容机制的,故无需重启 消息发送者、消息消费者,随着时间的推移,我们可以查看topic的所有队列都参与到了消息的负载中,如图所示:

在这里插入图片描述

我们可以清晰的看到,所有的16个队列(每个 broker 8个队列)都参与到了消息发送的,运维小哥愉快的完成了topic的扩容。

2、问题暴露


该 topic 被 5个消费组所订阅,突然接到通知,其中有两个消费组反馈,部分队列的消息没有被消费,导致下游系统并没有及时处理。

3、问题分析


当时到项目组提交到消息组时,我第一反应是先看消费者的队列,打开该主题的消费情况,如图所示:

在这里插入图片描述

发现队列数并没有积压,备注(由于生产是4主4从,每一个 broker上8个队列,故总共32个队列),当时由于比较急,并没有第一时间发现这个界面,竟然只包含一个消费者,觉得并没有消息积压,又由于同一个集群,其他消费组没有问题,只有两个消费组有问题,怀疑是应用的问题,就采取了重启,打印线程栈等方法。

事后诸葛亮:其实这完成是错误的,为什么这样说呢?因为项目组(业务方)已经告知一部分业务未处理,说明肯定有队列的消息积压,当根据自己的知识,结合看到的监控页面做出的判断与业务方反馈的出现冲突时,一定是自己的判断出了问题。

正在我们“如火如荼”的认定是项目有问题时,团队的另一成员提出了自己的观点,原来在得到业务方反馈时,他得知同一个主题,被5个消费组订阅,只有其中两个有问题,那他通过rocketmq-console来找两者的区别,找到区别,找到规律,就离解决问题的路近了。

他通过对比发现,出问题的消费组只有两个客户端在消费(通常生产环境是4节点消费),而没有出现问题的发现有4个进程都在处理,即发现现象:出错的消费组,并没有全员参与到消费。正如上面的图所示:只有其中一个进程在处理8个队列,另外8个队列并没有在消费。

那现在就是要分析为啥topic共有16个队列,但这里只有1个消费者队列在消费,另外一个消费者不作为?

首先根据RocketMQ 消息队列负载机制,2个消费者,只有1个消费者在消费,并且一个有一个明显的特点是,只有broker-a上的队列在消费,broker-b上的队列一个也没消费。

正在思考为啥会出现这种现象时,他又在思考是不是集群是不是broker-b(对应我们生产环境是broker-c、broker-d上的队列都未消费)是新扩容的机器?扩容的时候是不是没有把订阅关系在新的集群上创建?提出了疑问,接下来肖工就开始验证猜想,通过查阅broker-c、broker-d在我们系统中创建的时间是2018-4月的时候,就基本得出结论,扩容时并没有在新集群上创建订阅消息,故无法消费消息。

于是运维小哥使用运维工具创建订阅组,创建方法如图所示:

在这里插入图片描述

创建好消费组后,再去查看topic的消费情况时,另外一个消费组也开始处理消息了,如下图所示:

在这里插入图片描述

4、问题复盘


潜在原因:DefaultCluster 集群进行过一次集群扩容,从原来的一台消息服务器( broker-a )额外增加一台broker服务器( broker-b ),但扩容的时候并没有把原先的存在于 broker-a 上的主题、消费组扩容到 broker-b 服务器。

触发原因:接到项目组的扩容需求,将集群队列数从4个扩容到8个,这样该topic就在集群的a、b都会存在8个队列,但Broker不允许自动创建消费组(订阅关系),消费者无法从broker-b上队列上拉取消息,导致在broker-b队列上的消息堆积,无法被消费。

解决办法:运维通过命令,在broker-b上创建对应的订阅消息,问题解决。

经验教训:集群扩容时,需要同步在集群上的topic.json、subscriptionGroup.json文件。

RocketMQ 理论基础,消费者向 Broker 发起消息拉取请求时,如果broker上并没有存在该消费组的订阅消息时,如果不允许自动创建(autoCreateSubscriptionGroup 设置为 false),默认为true,则不会返回消息给客户端,其代码如下:

在这里插入图片描述

问题解决后,我们团队的成员也分享了一下他在本次排查问题的处理方法:寻找出现问题的规律、推断问题、 然后验证问题。规律可以是问题本身的规律 也可以是和正常对比的差。

  • 10
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于 RocketMQ,有一些常见的需要注意。以下是一些可能遇到的问题和解决方法: 1. 顺序消息的顺序性问题:RocketMQ支持按顺序发送和消费消息,但在某些情况下,可能会出现消息乱序的情况。这可能是因为消息发送和消费的并发性导致的。解决方法是确保发送和消费消息时的并发性能够处理好顺序问题,或者使用顺序消息的特性来保证消息的有序性。 2. 消息重复消费:当消费者遇到异常情况或网络问题时,可能会导致消息重复消费。这可以通过在消费端实现幂等性来解决,即在消费消息时,检查是否已经处理过该消息,避免重复处理。 3. 消息丢失:在某些情况下,消息可能会丢失。造成消息丢失的原因可能是网络问题、消息发送失败等。为了避免消息丢失,可以设置消息发送的可靠模式为同步或异步,并在发送失败时进行重试。此外,还可以开启 RocketMQ 的高可用模式,使用主备模式或集群模式来保证消息的可靠传输。 4. 消费者负载均衡问题:当消费者数量较多时,可能会出现消费者负载不均衡的情况,导致部分消费者负载过重,影响整体性能。可以通过调整消费者组的配置参数来解决这个问题,例如调整消费者的线程数、消息拉取的间隔时间等。 5. 消息堆积问题:如果消息的生产速度大于消费速度,可能会导致消息堆积的情况。当消息堆积过多时,可能会影响 RocketMQ 的性能和稳定性。可以通过增加消费者的数量或者调整消费者的处理能力来解决消息堆积问题。 以上是一些可能遇到RocketMQ和解决方法,希望对你有帮助!如果你有其他关于 RocketMQ 的问题,欢迎继续提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值