RocketMQ——队列位置信息

本文探讨了RocketMQ中队列位置信息(offset)的存储方式及其应用场景。在集群模式下,offset由Broker存储控制,广播模式下则存储在本地。DefaultMQPushConsumer采用PULL模式时,offset默认存储在JVM,不持久化,可通过LocalFileOffsetStore优化。消费者可以设置从最早或特定时间开始消费,并解释了读取位置设置的优先级。
摘要由CSDN通过智能技术生成

如何存储队列位置信息

结合具体的应用场景,难免会遇到重新消费某条消息,比如返回消息消费失败,让MQ重新投递,或者需要跳过某一段时间内的消息进行消费等情况,为了解决这些需求,都需要将队列位置信息offset进行存储。因此本文将分析offset的存储位置,以及如何调整offset的值。

  • 何为offset

在RocketMQ中,一种类型的消息会拥有一个Topic,为了提高并行消费能力,一个Topic会有多个Message Queue,那么offset就是指在某个Topic下的一条消息在某个Message Queue里的位置信息,通过offset就可以定位到这个消息本身的索引值,进而可以指示Consumer从某条消息后开始消费。

  • offset的设计

对于DefaultMQPushConsumer来说,默认是MessageModel.CLUSTERING,集群模式,也就是同一个Consumer Group中的多个消费者每个消费一部分,各自消费的消息是不同的,它是由Broker端存储、控制offset的值。使用的RemoteBrokerOffsetStore结构;在MessageModel.BROADCASTING,广播模式下,消费组的每个消费者都能消费这个Topic的全部消息,每个消费者之间相对独立,使用的LocalFileOffsetStore结构,把offset存到本地。(offsetStore使用JSON格式进行存储)
使用DefaultMQPushConsumer的时候,采用PULL模式,消费者不用关心offsetStore,只需要处理MQ给consumer推送的消息即可,但是如果使用DefaultMQPullConsumer,就需要自己处理offset,选择从哪里开始消费。

        consumer.start();
        Set<MessageQueue> queues = consumer.fetchSubscribeMessageQueues("Topic1");
        for(MessageQueue queue:queues){
   
            //long offset = consumer.fetchConsumeOffset(queue,true);//得到每一个相关联Queue起始的offset
            //System.out.println(queue.getQueueId()+" "+queue.getTopic()+" "+queue.getBrokerName()+"=> "+offset);
            for(;;){
   
                long _offset = map.get(queue)==null?0:map.get(queue);//得到queue后从map中去取
                PullResult pullResult = consumer.pullBlockIfNotFound(queue, null, _offset, MAX_NUM);
                //把下一次要读取的offset进行存储
                System.out.println("minOffset  "+pullResult.getMinOffset()+"  maxOffset  "+pullResult.getMaxOffset());
                long nextOffset = pullResult.getNextBeginOffset();
                System.out.println("nextBeginOffset  "+nextOffset);
                map.put(queue,nextOffset);
                List<MessageExt> msgList = pullResult.getMsgFoundList();
                if(null!=msgList){
   
                    for(MessageExt l:msgList){
   
                        System.out.println(l.getMsgId()+
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值