直接上代码
@Autowired
private KafkaListenerEndpointRegistry kafkaRegistry;
@Autowired
private ConsumerFactory<Object, Object> consumerFactory;
/**
* 设置一个监听器,消费kafka消息
* @param recored
* @param offset
* @param acknowledgment
*/
@KafkaListener(id = "testlistenerId", topics ={ "testTopic" }, groupId = "testGroupId",clientIdPrefix = "testClientId")
public void kafkaListener(String recored,@Header(KafkaHeaders.OFFSET) Integer offset,Acknowledgment acknowledgment)
{
System.out.println("1============================"+offset);
System.out.println("2============================"+recored.length());
System.out.println("3============================"+recored.substring(0,100));
acknowledgment.acknowledge();
}
/**
* 重置kafka的testTopic的分区号为0的offset
* @param offset
*/
public void startReStat(long offset)
{
//1、获取需要重置offset的topic的监听器停止,因为一个topic的分区只能有一个客户端操作
MessageListenerContainer messageListenerContainer = kafkaRegistry.getListenerContainer("testlistenerId");
if (messageListenerContainer!= null && !messageListenerContainer.isContainerPaused())
{
messageListenerContainer.pause();
}
if (messageListenerContainer!= null && messageListenerContainer.isRunning())
{
messageListenerContainer.stop();
}
//2、创建一个新的客户端(消费者)并设置需要重置offset的topic的分区(可实际情况设置,我的分区是0)
Consumer<Object, Object> cunsumer = consumerFactory.createConsumer("testGroupId", null);
cunsumer.assign(Arrays.asList(new TopicPartition("testTopic", 0)));
//3、重置指定topic的offset,并同步提交,提交后消费者会自动退出
cunsumer.seek(new TopicPartition("testTopic", 0), offset);
cunsumer.commitSync();
//4、重启启动监听器,原消费者继续消费kafka消息
if (messageListenerContainer!= null && !messageListenerContainer.isRunning())
{
messageListenerContainer.start();
messageListenerContainer.resume();
}
}
关键流程:
1、停止需要重置offset的topic的监听器,因为一个topic的分区只能有一个客户端操作
2、创建一个新的客户端(消费者)并设置需要重置offset的topic的分区
3、重置指定topic的offset,并同步提交,提交后消费者会自动退出
4、重启启动监听器,原消费者继续消费kafka消息