rocketmq一个不消费问题排查

零度    2019/08/06    总阅读量

高并发、锁   思考   面试   实践   Netty   Linux   Redis   MySQL   Nginx   Maven   Git   ElasticSearch   Spring  

结论

commitlog的文件序号错误,导致新生产的比老的小(2对应的文件序号比1的小),导致doReput一直操作不到数据,导致ConsumeQueue没数据进来,导致发送的可以正常发送,并且提升send_ok,并且通过message_id可以查询到数据,但是消费端就是消费不到数据。

备注: 这个问题就算重启rocketmq的broker也是不行的。必须手动处理,通过做法就是把2修改为00000000004294967296即可,或者删除1对应的文件即可。

问题现象以及观察、模拟

但是查看

代码模拟:

    public static void main(String[] args) throws MQClientException, InterruptedException {

        DefaultMQProducer producer = new DefaultMQProducer("test");
        producer.setNamesrvAddr("xxxxxxxx:9876");

        producer.start();

        for (int i = 0; i < 2; i++) {
            try {
                Message msg = new Message("test-topic" /* Topic */, "" /* Tag */, ("Hello RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET) /* Message body */);

                SendResult sendResult = producer.send(msg, new MessageQueueSelector() {
                    @Override
                    public MessageQueue select(List<MessageQueue> mqs, Message msg, Object arg) {

                        for (MessageQueue mq : mqs) {
                            if("broker-c".equals(mq.getBrokerName()) && mq.getQueueId()==2){
                                return mq;
                            }
                        }
                        return mqs.get(0);
                    }
                }, 0);

                System.out.printf("%s%n", sendResult);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        producer.shutdown();
    }

根据message_id的确可以查询到数据:

但是看这块broker数据没变

发送的数据对消费者不可见,但是消息的确发送成功了!

正常的情况应该是:

发送成功:

查看broker对应情况

这种情况才是正确的!

为什么有一个会出现这个情况呢????

问题排查定位

本质显示的offset代码为:

原始数据有,但是没有入consumerqueue数据是有问题的,需要从这块进行排查:

查看异常节点的线程栈(发现ReputMessageService这个线程是存在的,我还是怀疑这个线程意外退出了……所以这个情况就排除了)

发送数据之后:

原始文件的确在变

但是

这2个不变

正常的查看broker信息:

异常的broker上面的信息

为什么这个dispatchBehindBytes要落后这么多

看到这里,我们会发现就是doReput有问题????

正常情况:

另外一种有问题情况

有没有发现问题,居然比要小,rocketmq的commitlog生存是有规律的,默认是按照00000000000000000000、00000000001073741824、00000000002147483648 ,1073741824这个规律递增的。

由于这个问题,在doReput的时候,getDate的时候会调用下面方法,导致出错:

查看日志的确存在

问题解决

把这个文件名序号大的删除即可(或者修改新文件名为00000000004294967296),之后进行重启就可以了。

至于为什么会生成这样的新的序列没有老的大的情况还需要排查下………………(我猜可能是bug,逃……

查看数据类似如下:

如果磁盘紧张,那么把最小的文件删除了,是否就出现了今天的问题了。

github源代码地址:rocketmq,或者公号回复“rocketmq”获取源码地址。


扫描关注:匠心零度

(转载本站文章请注明作者和出处 匠心零度-jiangxinlingdu


腾讯云:新客户代金券
腾讯云:3年时长最低265元/年
阿里云:ECS云服务器2折起


目录