RocketMQ不能消费消息原因定位
一、问题
最近一个Spring Cloud微服务项目中定义的RocketMQ Consumer Bean不能正常触发消息消费。问题发生在测试环境。
这个功能以前是好的,生产环境和预发环境也是正常的。
二、定位
RocketMQ是阿里开源的用Java实现的消息中间件,广泛用于金融、电商等领域。
检查了一下Consumer Bean的定义,一切正常。按API要求定义了groupId,NameServer地址,Topic,Tag和Listener;Consumer Bean启动也正常,没有任何异常。
但是生产者成功发送消息后,Listener没有消费任何消息。
登陆RocketMQ管理控制台,看到Topic和消费组都存在。但是消费组下面从Consume Detail点击进去看不到订阅的topic。
也就是说虽然Consumer Bean虽然subscribe订阅topic成功了,实际没有成功!并且没有任何异常!
我们RocketMQ和应用部署比较复杂,使用了Docker Compose和Swarm,一开始怀疑是网络问题,因为代码在预发和生产环境是正常的,只是最近在开发测试环境消费失败。
但是奇怪的是其他消费组和topic也正常,说明RocketMQ也应该正常,问题应该在应用部署或者应用自身。
不同环境、不同topic和消费组对比一下后,还发现一个问题。出问题的消费组除了没有订阅预期的topic以外,还看到另外一个奇怪的topic。一开始没有特别关注这一点。
RocketMQ作者也不熟,除了面试八股文中背的“事务消息”,实操为0。各种AI Chat一圈无果。地铁上想到这两天“千问”APP火出圈了,都是阿里的亲儿子,知根知底,问问“千问”APP看。
Bingo,“千问”给的第一个方案让我想到前面消费组下面奇怪的topic,感觉就是这个原因了。
关闭非预期topic对应的消费应用后,重新启动我们消费应用,发现topic已经能正常订阅了。消费消息也就正常了。
三、结论
RocketMQ要求同一个消费组(Group ID)下的所有消费者实例,必须订阅完全相同的topic和Tag。否则会出现topic注册失败,消息不能消费的问题。
这点其实和Kafka的设计规范一致:同一个消费者组内的所有消费者必须订阅相同的主题。想想也对,如果topic不同,分区、再平衡策略和Offset管理就不好处理了。
“All consumers in the same group must subscribe to the same topics.”