持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情
问题描述
今天在测试环境遇到一个问题,测试环境MQ集群,生产者消息正常,但是消息不消费?
问题排查
1、 首先看下消息,生产者消息是存在的,但是没有被消费
2、查询topic对应的consumer实例,很诡异的现象没有订阅的信息
怀疑是服务启动的问题,查看服务的启动日志
[app@dzopdev-010010195187 itp]$ grep "crash_node_group" app.log
2022-06-20 08:20:33.846 [] INFO o.a.r.s.s.DefaultRocketMQListenerContainer - running container: DefaultRocketMQListenerContainer{consumerGroup='crash_node_group', nameServer='10.10.195.187:9876', topic='flow_crash_node_event', consumeMode=CONCURRENTLY, selectorType=TAG, selectorExpression='*', messageModel=CLUSTERING}
2022-06-20 08:20:33.899 [] INFO o.a.r.s.s.DefaultRocketMQListenerContainer - running container: DefaultRocketMQListenerContainer{consumerGroup='crash_node_group', nameServer='10.10.195.187:9876', topic='party_crash_node_event', consumeMode=CONCURRENTLY, selectorType=TAG, selectorExpression='*', messageModel=CLUSTERING}
一个consumer_group对应了两个topic, 会不会是这个出了问题,重新命名party_crash_node_group和flow_crash_node_group问题解决,consumer可以消费到对应topic下面的消息了。
原因分析
那么就存在问题了,那一个consumer_group是否支持多个topic,按道理是支持这种方式的,我们通过单测和源码看下为什么会导致上面的这个现象?
我们先创建一个测试的工程,创建两个consumer监听两个不同的topic,但是用的ConsumerGroup。 按照我们的理解,多个ConsumerGroup只有一个ConsumerGroup能消费,但是我两个监听不同的Topic肯定只能有一个监听到对应topic消息,另外一个则消费不到。
@Slf4j
@Component
@RocketMQMessageListener(consumerGroup = "test_node_group", topic = "party_test_event")
public class FlowNodeEventConsumer implements RocketMQListener<MessageExt> {
@Override
public void onMessage(MessageExt messageExt) {
byte[] body = messageExt.getBody();
String message = new String(body, StandardCharsets.UTF_8);
System.out.println(message);
log.info("FlowNodeEventConsumer onMessage :{}", message);
}
}
@Slf4j
@Component
@RocketMQMessageListener(consumerGroup = "test_node_group", topic = "flow_test_event")
public class PartyNodeEventConsumer implements RocketMQListener<MessageExt> {
@Override
public void onMessage(MessageExt messageExt) {
byte[] body = messageExt.getBody();
String message = new String(body, StandardCharsets.UTF_8);
System.out.println(message);
log.info("PartyNodeEventConsumer onMessage :{}", message);
}
}
@Test
void contextLoads() {
String s = "{"id":95,"taskId":40,"step":3,"triggerCode":1002,"ruleExpression":"{\"billingModel\":0,\"dataApiId\":116}","status":2,"offset":0,"updateTime":"2022-06-16 16:41:59","createTime":"2022-06-16 16:37:53"}";
for (int i =0; i < 10; i++) {
rocketMQTemplate.convertAndSend("party_test_event", s);
}
}
10条消息中有的被消费有的没有被消息
有的已经消费了。
总结
这个其实是一个用法上的错误,同一个ConsumerGroup多个topic,消息消费的时候,同一个ComsumerGroup只有一个Consumer可以消费,但是我们监听上写死了topic,其他的topic是监听不到的。 如果有这种场景可以监听不同的tag然后处理。 但是console这边显示的感觉还是有点问题,明天通过源码来分析一下整个ConsumerGroup的原理和处理流程。