kafka监听topic消费_Spring-Kafka(六)—— @KafkaListener的花式操作

本文详细介绍了Spring-Kafka中使用@KafkaListener进行消息监听的各种方式,包括单条和批量消费、ACK机制、手动提交偏移量等。讲解了如何配置监听容器工厂、监听异常处理器、不同参数类型的监听方法,并展示了如何通过@KafkaListener的topicPartitions属性监听特定分区。此外,还讨论了如何在监听中使用ConsumerRecord类和实现消息头与消息体的获取,以及如何利用Ack机制实现消息确认和拒绝。
摘要由CSDN通过智能技术生成

消息监听

对于Kafka中Topic的数据消费,我们一般都选择使用消息监听器进行消费,怎么把消息监听器玩出花来呢,那就得看看它所实现的功能了。

Spring-Kafka中消息监听大致分为两种类型,一种是单条数据消费,一种是批量消费;两者的区别只是在于监听器一次性获取消息的数量。GenericMessageListener是我们实现消息监听的一个接口,向上扩展的接口有非常多,比如:单数据消费的MessageListener、批量消费的BatchMessageListener、还有具备ACK机制的AcknowledgingMessageListener和BatchAcknowledgingMessageListener等等。接下来我们就一一解析一下。

GenericMessageListener

这里可以看到GenericMessageListener使用注解标明这是一个函数式接口,默认实现了三种不同参数的onMessage方法。data就是我们需要接收的数据,Consumer则是消费者类,Acknowledgment则是用来实现Ack机制的类。这里需要注意一下的是,Consumer对象并不是线程安全的。

@FunctionalInterface

public interface GenericMessageListener {

void onMessage(T var1);

default void onMessage(T data, Acknowledgment acknowledgment) {

throw new UnsupportedOperationException("Container should never call this");

}

default void onMessage(T data, Consumer, ?> consumer) {

throw new UnsupportedOperationException("Container should never call this");

}

default void onMessage(T data, Acknowledgment acknowledgment, Consumer, ?> consumer) {

throw new UnsupportedOperationException("Container should never call this");

}

}

接下来先浏览一下继承了GenericMessageListener接口的类。前缀为Batch的接口都是批处理类型的消息监听接口,里面的参数也都讲解过了

public interface MessageListener {

void onMessage(ConsumerRecord data);

}

public interface AcknowledgingMessageListener {

void onMessage(ConsumerRecord data, Acknowledgment acknowledgment);

}

public interface ConsumerAwareMessageListener extends MessageListener {

void onMessage(ConsumerRecord data, Consumer, ?> consumer);

}

public interface AcknowledgingConsumerAwareMessageListener extends MessageListener {

void onMessage(ConsumerRecord data, Acknowledgment acknowledgment, Consumer, ?> consumer);

}

public interface BatchMessageListener {

void onMessage(List> data);

}

public interface BatchAcknowledgingMessageListener {

void onMessage(List> data, Acknowledgment acknowledgment);

}

public interface BatchConsumerAwareMessageListener extends BatchMessageListener {

void onMessage(List> data, Consumer, ?> consumer);

}

public interface BatchAcknowledgingConsumerAwareMessageListener extends BatchMessageListener {

void onMessage(List> data, Acknowledgment acknowledgment, Consumer, ?> consumer);

}

在把@KafkaListener玩出花前,我们还需要了解怎么使用非注解方式去监听Topic。

我们在创建监听容器前需要创建一个监听容器工厂,这里只需要配置一下消费者工厂就好了

,之后我们使用它去创建我们的监听容器。consumerFactory()这个参数在之前就已经定义过了,这里就不重复贴代码了。

@Bean

public ConcurrentKafkaListenerContainerFactory kafkaListenerContainerFactory() {

ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory<>();

factory.setConsumerFactory(consumerFactory());

return factory;

}

有了监听容器工厂,我们就可以使用它去创建我们的监听容器

Bean方式创建监听容器

@Bean

public KafkaMessageListenerContainer demoListenerContainer() {

ContainerProperties properties = new ContainerProperties("topic.quick.bean");

properties.setGroupId("bean");

properties.setMessageListener(new MessageListener() {

private Logger log = LoggerFactory.getLogger(this.getClass());

@Override

public void onMessage(ConsumerRecord record) {

log.info("topic.quick.bean receive : " + record.toString());

}

});

return new KafkaMessageListenerContainer(consumerFactory(), properties);

}

启动项目我们可以看一下控制台的日志,监听容器成功分配给某个消费者的结果很清晰的显示出来了,顺便就写个测试方法测试一下监听器能不能正常运行。

2018-09-11 10:36:15.732 INFO 1168 --- [erContainer-C-1] o.a.k.c.c.internals.AbstractCoordinator : [Consumer clientId=consumer-4, groupId=bean] Successfully joined group with generation 1

2018-09-11 10:36:15.733 INFO 1168 --- [erContainer-C-1] o.a.k.c.c.internals.ConsumerCoordinator : [Consumer clientId=consumer-4, groupId=bean] Setting newly assigned partitions [topic.quick.bean-0]

2018-09-11 10:36:15.733 INFO 1168 --- [erContainer-C-1] o.s.k.l.KafkaMessageListenerContainer : partitions assigned: [topic.quick.bean-0]

@Test

public void test() {

kafkaTemplate.send("topic.quick.bean", "send msg to beanListener");

}

@KafkaListener参数讲解

在前几章入门的时候就已经写过一个用@KafkaListener注解实现监听的代码,这里就贴一下之前写的代码

@KafkaListener(id = "demo", topics = "topic.quick.demo")

public void listen(String msgData) {

log.info("demo receive : "+msgData);

}

使用@KafkaListener这个注解并不局限于这个监听容器是单条数据消费还是批量消费,区分单数据还是多数据消费只需要配置一下注解的containerFactory属性即可,先讲解一下这个监听方法都能接收写什么参数吧。

data : 对于data值的类型其实并没有限定,根据KafkaTemplate所定义的类型来决定。data为List集合的则是用作批量消费。

ConsumerRecord:具体消费数据类,包含Headers信息、分区信息、时间戳等

Acknowledgment:用作Ack机制的接口

Consumer:

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值