记一次故障排查:rocketmq消费状态NOT_CONSUME_YET
一、故障状态
消息发送成功,但是消费状态都为NOT_CONSUME_YET

image.png
二、trackType状态含义
通过查询RocketMQ-Dashboard的源码
 public enum TrackType {
    CONSUMED,               //  消息已经被消费
    CONSUMED_BUT_FILTERED,  //  消息已经投递但被过滤
    PULL,                   //  消息消费的方式是拉模式
    NOT_CONSUME_YET,        //  目前没有被消费
    NOT_ONLINE,            //   CONSUMER不在线
    UNKNOWN                //   未知错误
}
“已消费”是如何定义的?
broker中有个map用来保存每个queue的消费进度,如果queue的offset大于被查询消息的offset则消息被消费否则没有被消费。
三、查看消息分布情况

在当前group下,都集中在broker-a 下queue0中,最后的消费时间lastTimeStamp,正好是发生事故状态的时间点。
四、大胆假设
producer可能将消息都发送到broker-a 下queue0,而没有相应的consumer去消费此队列下的数据,导致现在故障发生。
五、确定消息的发送队列----- 隐藏技能
通过查看RocketMQ-Dashboard的源码,发现Dashboard其实返回了消息的很多信息,但是并没有在页面展示出来,直接看接口返回。如此我们确定了消息的发送队列

六、解决
生产者负载均衡的策略,与消费者的负载均衡策略不同,导致未能正常消费
解决方案: 修改消费的这消费queue,问题解决。
RocketMQPushConsumerLifecycleListener 文件
  @Override
    public void prepareStart(DefaultMQPushConsumer consumer) {
        // set consumer consume message from now
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_TIMESTAMP);
        consumer.setConsumeTimestamp(UtilAll.timeMillisToHumanString3(System.currentTimeMillis()));
        AllocateMessageQueueStrategyUtil.setUpAllocateStrategy(consumer);
    }
// 文件 AllocateMessageQueueStrategyUtil
public final class AllocateMessageQueueStrategyUtil {
    /** 构造方法 */
    private AllocateMessageQueueStrategyUtil() {
    }
    //"CHECKSTYLE:OFF"
    /** 分配策略 */
    static AllocateMessageQueueStrategy allocateMessageQueueStrategy = new AllocateMessageQueueStrategy() {
        @Override
        public List<MessageQueue> allocate(String consumerGroup, String currentCID, List<MessageQueue> queueList,
                                           List<String> cidAll) {
            String allocateStrategy = SpringActiveProfileUtil.getBean("nacosProperties", NacosProperties.class)
                    .getMqAllocateStrategy();
            List<MessageQueue> list = new ArrayList<>();
            Integer strategyInteger = Integer.valueOf(allocateStrategy);
            list.add(queueList.get(strategyInteger));
            return list;
        }
        @Override
        public String getName() {
            return "divide_by_queue";
        }
    };
    /**
     * 设置分配策略
     * @param consumer consumer
     */
    public static void setUpAllocateStrategy(DefaultMQPushConsumer consumer) {
        if (SpringActiveProfileUtil.getActiveProfile().equals("test")
                || SpringActiveProfileUtil.getActiveProfile().equals("dev")) {
            consumer.setAllocateMessageQueueStrategy(AllocateMessageQueueStrategyUtil.allocateMessageQueueStrategy);
        }
    }
}

 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号