RocketMQ OFFSET_ILLEGAL导致消息重新消费 BUG排查

本文详细记录了一个由于OFFSET_ILLEGAL导致RocketMQ消息重复消费的问题。问题出现在应用重启和MQ服务器切换期间,经过分析和排查,发现是由于应用在从节点超时后请求了错误的offset,并在主节点上被置零。解决方案包括修复网络策略和调整代码逻辑以确保幂等性。
摘要由CSDN通过智能技术生成

表象


  1. 01-17 16:57重启了多个服务器,包括应用和MQ。
  2. 重启步骤是先重启应用,后重启MQ主节点,再是MQ从节点重启
  3. 之后就是应用重新消费了01-12以来的所有消息

分析


思来想去,可能的原因有:

  • offset没有更新到broker
  • 重复投递?
  • offset被应用修改了

前两点日志中没有相关的蛛丝马迹,而关于第三点则发现日志中有warn

[2021-01-17 17:02:58] WARN  com.consumer.PriorityPullConsumer 243 lambda$startConsume$1 - msgqueue MessageQueue [topic=MT_MQ_L4, brokerName=broker-b, queueId=3] offset illegal,fix to 228871.

。。。offset被修改了。。。

相关的代码如下:

long offset = offsetManager.fetchConsumeOffset(consumer, mq);
PullResult pullResult = consumer.pull(mq, msgSelector, 	                                             	        offset,maxPullFrameSize);
// 省略无关代码
if(pullResult.getPullStatus() == PullStatus.OFFSET_ILLEGAL){
   
    consumer.updateConsumeOffset(mq, pullResult.getNextBeginOffset());
    LOG.warn("msgqueue {} offset illegal,fix to 			   {}.",mq,pullResult.getNextBeginOffset());
}

问题来了,为啥会PullStatus.OFFSET_ILLEGAL ???

排查


  • rocketmq_client.log中发现:

    2021-01-17 00:00:07,573 createChannel: connect remote host[mq4:10911] timeout 3000ms
    2021-01-17 00:00:10,574 createChannel: connect remote host[mq3:10911] timeout 3000ms
    

    连接3s超时了。。。部署架构是双主双从,而mq3 mq4就是从节点。

    问一下技术支持,技术支持部署时没有开通应用连接从节点的网络策略。。。

    又一个问题是,即使连不上从节点,那么只有主节点,就算主节点宕机,当主节点重启后,为啥会返回PullStatus.OFFSET_ILLEGAL

  • broker.log日志中发现:

    2021-01-17 16:57:50 INFO PullMessageThread_21 - the request offset too small [requestOffset=0, brokerMinOffset=159611]
    

    相关代码如下:

    minOffset = consumeQueue.getMinOffsetInQueue();
    maxOffset = consumeQueue.getMaxOffsetInQueue();
    
    if (maxOffset == 0) {
         
        status = GetMessageStatus.NO_MESSAGE_IN_QUEUE;
        nextBeginOffset = nextOffsetCorrection
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值