Pulsar 消费重置,移动偏移量有6种方法
- 设置subscriptionInitialPosition,在创建consume的时候处理。
- consumer.seek(messageId)方式。
- admin.topics().peekMessages(topicName,subsciptionName,numMessages)方式。
- admin.topics().resetCursor(topicName,subsciptionName,messageTimestamp)方式。
- admin.topics().skipMessages(String topic, String subName, long numMessages)方式。
- admin.topics().skipAllMessages(String topic, String subName)方式。
以下讲解一下楼主对他们的理解和测试。
1. 设置subscriptionInitialPosition
创建consume的时候我们可以指定subscriptionInitialPosition(SubscriptionInitialPosition.Earliest)
参数;
已经支持的有SubscriptionInitialPosition.Earliest
和SubscriptionInitialPosition.Latest
,顾名思义,一个是回滚到最初,一个是最新接受到的消息。目标是对某个订阅而言;
源码中摘下的使用实例如下:
PulsarClient client = PulsarClient.builder().serviceUrl(pulsar.getBrokerServiceUrl()).build();
CompletableFuture<Producer<String>> producerFuture = client.newProducer(Schema.STRING)
.topic(topicName)
.createAsync();
CompletableFuture<Consumer<String>> consumerFuture = client.newConsumer(Schema.STRING)
.topic(topicName)
.subscriptionName("sub")
.subscriptionInitialPosition(SubscriptionInitialPosition.Earliest)
.subscribeAsync();
CompletableFuture.allOf(producerFuture, consumerFuture).get();
Producer<String> producer = producerFuture.get();
Consumer<String> consumer = consumerFuture.get();
for (int i = 0; i < N; i++) {
producer.send("Hello-" + i);
}
consumer.close();
producer.close();
2. consumer.seek(messageId)
重置游标
pulsar中有分区topic和非分区topic的区分,现在api只支持创建分区topic,例如我们创建了一个分
topic(persistent://zhiwang3/whds9/admin2),然后创建分区topic的consume,此时我们发现分区topic的consume不支持seek功能。
-
分区topic不支持seek功能
-
非分区topic支持seek功能
楼主的做法是采用分区topic的一个分区来创建consume,例如分区topic的其中一个分区(persistent://zhiwang3/whds9/admin2-partition-0),再次创建consume,支持seek功能。游标回滚到messageId的位置。
3. peekMessages(topicName,subsciptionName,numMessages)
查询消费者消费到的numMessages条消息。
- 支持非分区主题(此结论借鉴网上其他博客,还未验证)
- 不支持分区主题,直接返回null(实测有效)
源码解释:
/**
* Peek messages from a topic subscription.
*
* @param topic topic name
* @param subName Subscription name
* @param numMessages Number of messages
* @return
* @throws NotAuthorizedException Don't have admin permission
* @throws NotFoundException Topic or subscription does not exist
* @throws PulsarAdminException Unexpected error
*/
List<Message<byte[]>> peekMessages(String topic, String subName, int numMessages) throws PulsarAdminException;
4. resetCursor(topicName,subsciptionName,messageTimestamp)
重置游标,
- 分区topic支持方法(实测有效)
CompletableFuture resetCursorAsync(String topic, String subName, long timestamp);
参数解释
/**
* Reset cursor position on a topic subscription.
*
* @param topic
* topic name
* @param subName
* Subscription name
* @param timestamp
* reset subscription to position closest to time in ms since epoch/即你想回到哪个时刻的消费位置timestamp就设置为时刻的millions表示
*
*/
CompletableFuture<Void> resetCursorAsync(String topic, String subName, long timestamp);
- 非分区topic支持方法(实测有效)
void resetCursor(String topic, String subName, MessageId messageId) throws PulsarAdminException;
参数解释:
/**
* Reset cursor position on a topic subscription.
*
* @param topic
* topic name
* @param subName
* Subscription name
* @param messageId
* reset subscription to messageId (or previous nearest messageId if given messageId is not valid)/你可以定义自己的messageId,也可以直接使用已经定义好的MessageId.earliest或MessageId.latest(MessageId.earliest来指向topic上最早
可用的消息,使用MessageId.latest指向最新的消息)
*/
CompletableFuture<Void> resetCursorAsync(String topic, String subName, MessageId messageId);
5. admin.topics().skipMessages(String topic, String subName, long numMessages)
- 不支持分区topic
这点可以从源码的测试代码块看出:
//final String partitionedTopicName = "persistent://prop-xyz/ns1/" + topicName;
assertEquals(Sets.newHashSet(admin.topics().getList("prop-xyz/ns1")),
Sets.newHashSet(partitionedTopicName + "-partition-0", partitionedTopicName + "-partition-1",
partitionedTopicName + "-partition-2", partitionedTopicName + "-partition-3"));
try {
admin.topics().skipMessages(partitionedTopicName, "my-sub", 5);
fail("skip messages for partitioned topics should fail");
} catch (Exception e) {
// ok
}
6. admin.topics().skipAllMessages(String topic, String subName)
直接跳过所有未被消费的消息。
- 支持分区和非分区两种topic(实测有效,源码测试代码也可看出)
参考文章:
Pulsar 游标回滚,移动偏移量测试