• RocketMQ问题


    RocketMQ原理(4)——消息ACK机制及消费进度管理

    RocketMQ消费者,设置setConsumeFromWhere无效的问题

    MQ的CONSUME_FROM_LAST_OFFSET未生效

    问题描述

    把优惠券消费的ROMA的topic从单库的roma_promcenter改为TDDL的roma_promcore(roma_promcore这个topic随着TDDL已经提早上线2天)。希望从队列的尾部开始消费,roma的consumer默认是从尾部开始消费(CONSUME_FROM_LAST_OFFSET),应该没有问题。但是上线后发现还是从队列的头部开始消费,好在我们代码里面做了幂等,没有引起故障。

    解析

    集群消费模式下,消费进度offset存储在boker中,以comsumeGroup+queue作为key,标识一个消费者组在这个queue上的消费进度,由消费者定时将此offset同步到broker上。

    ------RocketMQ采取的是定期批量ack的机制以持久化消费进度。也就是说每次消费消息结束后,并不会立刻ack,而是定期的集中的更新进度。 由于持久化不是立刻持久化的,所以如果消费实例突然退出(如断电)或者触发了负载均衡分consue queue重排,有可能会有已经消费过的消费进度没有及时更新而导致重新投递。

    消费均是客户端发起Pull请求的,告诉消息的offset位置,broker去查询并返回。在响应体中,broker会返回下一次应该拉取的位置,PushConsumer通过这一个位置,更新自己下一次的pull请求。这样就保证了正常情况下,消息只会被投递一次。

    问题的原因就在于只有全新的消费组才会使用到这些策略,老的消费组都是按已经存储过的消费进度继续消费。

    当消息一直在produce,但是一直没有消费、在堆积,offset=0。老的消费者组中新加的监听topic,会从0开始消费。

    如果消息有删除(比如3天后删除消息),offset不为0,那就按CONSUME_FROM_LAST_OFFSET,从尾部开始消费消息。

    对于老消费组想跳过历史消息可以采用以下两种方法:

    1. 代码按照日期判断,太老的消息直接return CONSUME_SUCCESS过滤。
    2. 代码判断消息的offset和MAX_OFFSET相差很远,认为是积压了很多,直接return CONSUME_SUCCESS过滤。
    3. 消费者启动前,先调整该消费组的消费进度,再开始消费。可以人工使用命令resetOffsetByTime,或调用内部的运维接口,详见ResetOffsetByTimeCommand.java
  • 相关阅读:
    Centos7如何安装开源办公软件Libreoffice
    vi/vim输入中文乱码,无法输入中文解决方法
    NFS+Rsync增量备份方案
    完全备份,增量备份,差异备份及恢复区别
    Centos7安装Windows程序,例如QQ,微信,notepad++等exe程序
    Centos7升级内核后,导致打开VMware提示需要安装vmmon和vmnet模块
    SSH安全加固
    PHP使用mail函数发送邮件
    Centos7使用mail命令发送邮件
    Python部署配置Django架构教程
  • 原文地址:https://www.cnblogs.com/fanguangdexiaoyuer/p/11536267.html
Copyright © 2020-2023  润新知