rocketmq--offset功能及demo

在RocketMQ中,Offset(偏移量)是用来标识消费者在消息队列中的位置。每个消费者维护一个Offset,以便知道下一次从哪里开始消费。Offset的作用包括:

  1. 确保消息不丢失:通过持久化Offset,即使在消费者宕机后重启,也能从上次消费的位置继续消费,保证消息至少被消费一次。

  2. 消息重试:如果消费失败,可以根据Offset重新消费消息。

  3. 消息顺序:对于顺序消息,通过维护Offset可以保证消息的顺序消费。

  4. 避免消息重复:确保每条消息只被消费一次,消费者在成功处理消息后更新Offset。

  5. 跳过已处理消息:如果消费者只想从最新的消息开始消费,可以通过设置Offset来实现。

下面是一个基于Spring Boot的关于RocketMQ Offset的应用示例。在这个示例中,我们将创建一个消费者,它会手动管理Offset。

首先,在pom.xml中添加RocketMQ的依赖:

<dependency>
    <groupId>org.apache.rocketmq</groupId>
    <artifactId>rocketmq-spring-boot-starter</artifactId>
    <version>2.1.0</version>
</dependency>

配置application.propertiesapplication.yml文件:

rocketmq:
  name-server: 127.0.0.1:9876 # 修改为实际的RocketMQ NameServer地址
  consumer:
    group: my-consumer-group # 消费者组名
    consume-thread-max: 20
  producer:
    group: my-producer-group # 生产者组名

创建消费者服务并手动管理Offset:

import org.apache.rocketmq.client.consumer.DefaultLitePullConsumer;
import org.apache.rocketmq.client.consumer.PullResult;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.common.message.MessageQueue;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Set;

@Service
public class ManualOffsetConsumerService {
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    
    private DefaultLitePullConsumer consumer;

    @PostConstruct
    public void init() throws Exception {
        consumer = new DefaultLitePullConsumer("my-consumer-group");
        consumer.setNamesrvAddr("127.0.0.1:9876");
        consumer.start();
    }

    public void consume() throws Exception {
        Set<MessageQueue> messageQueues = consumer.fetchSubscribeMessageQueues("test-topic");
        for (MessageQueue mq : messageQueues) {
            long offset = consumer.fetchConsumeOffset(mq, true);
            PullResult pullResult = consumer.pull(mq, "*", offset, 32);
            List<MessageExt> messages = pullResult.getMsgFoundList();
            if (messages != null) {
                for (MessageExt message : messages) {
                    // 处理业务逻辑
                    System.out.println(new String(message.getBody()));
                }
                // 更新Offset
                consumer.updateConsumeOffset(mq, pullResult.getNextBeginOffset());
            }
        }
    }
}

在这个例子中,我们使用了DefaultLitePullConsumer来手动拉取消息,并且在处理完消息后手动更新Offset。fetchSubscribeMessageQueues方法用于获取指定Topic的所有队列,fetchConsumeOffset用于获取指定队列的当前消费Offset,pull方法用于拉取指定数量的消息,updateConsumeOffset用于更新消费的Offset。

注意:此代码仅为示例,实际使用时需要根据具体业务场景进行调整。在生产环境中,你可能需要更复杂的错误处理逻辑,以及确保Offset的持久化和一致性。

在实际的应用中,你可以设置一个定时任务去调用consume

posted @ 2024-01-23 16:49  xylfjk  阅读(226)  评论(0编辑  收藏  举报