rocketmq--offset功能及demo
在RocketMQ中,Offset(偏移量)是用来标识消费者在消息队列中的位置。每个消费者维护一个Offset,以便知道下一次从哪里开始消费。Offset的作用包括:
-
确保消息不丢失:通过持久化Offset,即使在消费者宕机后重启,也能从上次消费的位置继续消费,保证消息至少被消费一次。
-
消息重试:如果消费失败,可以根据Offset重新消费消息。
-
消息顺序:对于顺序消息,通过维护Offset可以保证消息的顺序消费。
-
避免消息重复:确保每条消息只被消费一次,消费者在成功处理消息后更新Offset。
-
跳过已处理消息:如果消费者只想从最新的消息开始消费,可以通过设置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.properties
或application.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