一个ConsumerGroup多个Topic问题分析

872 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情

问题描述

今天在测试环境遇到一个问题,测试环境MQ集群,生产者消息正常,但是消息不消费?

问题排查

1、 首先看下消息,生产者消息是存在的,但是没有被消费

1655706681489_2C8D5DB9-5121-49b7-99E9-D5E3E663EDAC.png

2、查询topic对应的consumer实例,很诡异的现象没有订阅的信息 lQLPJxZrwd-JSjDNAs_NBz6ws9c4Tll56LkCsZ2rPcDnAA_1854_719.png

怀疑是服务启动的问题,查看服务的启动日志

[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下面的消息了。

image.png

原因分析

那么就存在问题了,那一个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);
    }
}

image.png

10条消息中有的被消费有的没有被消息

image.png

image.png 有的已经消费了。

总结

这个其实是一个用法上的错误,同一个ConsumerGroup多个topic,消息消费的时候,同一个ComsumerGroup只有一个Consumer可以消费,但是我们监听上写死了topic,其他的topic是监听不到的。 如果有这种场景可以监听不同的tag然后处理。 但是console这边显示的感觉还是有点问题,明天通过源码来分析一下整个ConsumerGroup的原理和处理流程。