springboot集成整合kafka-生产者拦截器ProducerInterceptor

写在前面:各位看到此博客的小伙伴,如有不对的地方请及时通过私信我或者评论此博客的方式指出,以免误人子弟。多谢! 

在之前的两篇文章,对于生产者而言,我们做到了使用KafkaTemplate发送消息、将消息发送到指定partition、我们还使用了带回调的addCallback方法判断消息是发送成功还是失败,并做下一步处理,今天再完善一下关于消费者的使用。

想个场景,咱们在玩游戏的时候,是不是经常因为队友太菜,对面太强而破口大骂呢,当你打字骂人的时候,有很多字是发不出去的,都会被替换为**类似的字符,对于kafka的生产者其实也有类似的功能,在消息发送之前对消息进行定制化处理,即:生产者拦截器ProducerInterceptor。生产者拦截器既可以用来在消息发送前做一些准备工作,比如按照某个规则过滤掉不符合要的消息、修改消息的内容等,也可以用来在发送回调逻辑前做一些定制化的需求,比如统计类工作。

感觉学一个东西困难的不是怎么学,而是不知道它能干嘛,知道了它能干嘛结合官方文档和网上大佬们的博客,学起来还是挺容易的,就像这篇生产者拦截器的使用,其实很简单,只要实现ProducerInterceptor接口,并重写它的方法就可以,关键是我知不知道有生产者拦截器这个事,废话不多说,直接贴一下生产者拦截器的测试代码:

@Component
public class CustomProducerInterceptor implements ProducerInterceptor {

    /**
     * 将消息序列化和计算分区之前调用,对消息进行定制化操作
     */
    @Override
    public ProducerRecord onSend(ProducerRecord record) {
        String newValue = "prefix:" + record.value();
        ProducerRecord producerRecord = new ProducerRecord(record.topic(),newValue);
        return producerRecord;
    }

    @Override
    public void onAcknowledgement(RecordMetadata metadata, Exception exception) {

    }

    @Override
    public void close() {

    }

    @Override
    public void configure(Map<String, ?> configs) {

    }
}

如上,从ProducerInterceptor接口的实现方法名就大体猜到onSend方法就是对消息的处理方法,我在方法中只是在消息前加了一个前缀简单测试下,具体的处理根据实际需求来。

要使自定义的拦截器生效,需要配置一下,在KafkaProducerConfig类中producerConfigs方法追加如下代码:

// 配置生产者拦截器
props.put(ProducerConfig.INTERCEPTOR_CLASSES_CONFIG,"com.example.springbootkafka.interceptor.CustomProducerInterceptor");

启动项目,访问http://localhost:8080/send3?message=test3 结果如下:

控制台打印的消息加上了prefix:前缀,说明配置的拦截器生效了。

一般要是处理逻辑复杂的话,可以将onSend中的处理逻辑拿出来,我单独建了一个工具类,用来处理消息,代码如下:

@Component
public class SendMessageInterceptorUtil {

    public ProducerRecord execute(ProducerRecord record) {
        System.out.println("====== 处理消息 ======");
        String newValue = "prefix:" + record.value();
        ProducerRecord producerRecord = new ProducerRecord(record.topic(),newValue);
        return producerRecord;
    }
}

然后在CustomProducerInterceptor住注入SendMessageInterceptorUtil,在onSend中调用,如下:

    @Autowired
    private SendMessageInterceptorUtil sendMessageInterceptorUtil;    

    @Override
    public ProducerRecord onSend(ProducerRecord record) {
        return sendMessageInterceptorUtil.execute(record);
    }

启动项目,访问http://localhost:8080/send3?message=test3 结果如下:

如上,不但拦截器没生效,而且注入的SendMessageInterceptorUtil为空,还报空指针的错误了,网上百度了一会也没搜到有用的信息,看着拦截器中的configure方法名像是加载配置的,看看它是个啥,

从结果看这个方法应该是加载生产者配置的,可以试一下将刚才定义的处理类加到configs中再试下,如下:

// 配置拦截器消息处理类
props.put("interceptorUtil","com.example.springbootkafka.util.SendMessageInterceptorUtil");
@Override
public void configure(Map<String, ?> configs) {
    System.out.println("======" + configs + "======");
    sendMessageInterceptorUtil = (SendMessageInterceptorUtil) configs.get("interceptorUtil");
}

启动项目,访问http://localhost:8080/send3?message=test3 结果如下:

从错误类转换异常可以知道,只要直接设置SendMessageInterceptorUtil对象就可以了,咱之前设置的类路径它解析不了,当做字符串处理了,改下:

// 配置拦截器消息处理类
SendMessageInterceptorUtil sendMessageInterceptorUtil = new SendMessageInterceptorUtil();
props.put("interceptorUtil",sendMessageInterceptorUtil);

启动项目,访问http://localhost:8080/send3?message=test3 结果如下:

可以看到消息发送成功了,同时也说明kafka的拦截器由kafka进行管理和spring无关。所以无法使用Spring依赖注入功能。但是我们可以将需要的bean添加到kafka配置,使用拦截器提供的config()方法来手动来获取这些bean依赖。

对于拦截器中的close()方法,负责关闭拦截器时执行资源的清理工作;onAcknowledgement方法:消息应答之前或者消息发送失败时调用,先于用户设定的Callback之前执行,这个方法运行在Producer的I/O线程中,实现逻辑越简单越好,否则影响消息发送速度。

看网上有好多统计消息发送成功失败条数的文章,感兴趣的小伙伴可以参考这篇试一下https://www.cnblogs.com/huxi2b/p/7072447.html  这篇还是比较全的。

顺便提下,除了生产者有拦截器,其实消费者也有消费者拦截器,类似生产者拦截器,实现消费者拦截器只要实现ConsumerInterceptor接口,重写它的方法即可,代码就不贴了。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在springboot集成kafka生产者,需要遵循以下步骤: 1. 添加Maven依赖 在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>org.springframework.kafka</groupId> <artifactId>spring-kafka</artifactId> <version>2.7.2</version> </dependency> ``` 2. 配置Kafka生产者 在application.properties文件中添加Kafka的配置: ```properties spring.kafka.producer.bootstrap-servers=<broker地址> spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer spring.kafka.producer.value-serializer=org.apache.kafka.common.serialization.StringSerializer ``` 3. 创建Kafka生产者 在代码中创建Kafka生产者: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.kafka.core.KafkaTemplate; import org.springframework.stereotype.Service; @Service public class KafkaProducerService { private final KafkaTemplate<String, String> kafkaTemplate; @Autowired public KafkaProducerService(KafkaTemplate<String, String> kafkaTemplate) { this.kafkaTemplate = kafkaTemplate; } public void sendMessage(String topic, String message) { this.kafkaTemplate.send(topic, message); } } ``` 4. 发送消息 在需要发送消息的地方,注入KafkaProducerService,并调用sendMessage方法: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @RestController public class MessageController { private final KafkaProducerService kafkaProducerService; @Autowired public MessageController(KafkaProducerService kafkaProducerService) { this.kafkaProducerService = kafkaProducerService; } @PostMapping("/message") public void sendMessage(@RequestBody String message) { this.kafkaProducerService.sendMessage("test-topic", message); } } ``` 以上就是在springboot集成Kafka生产者的步骤。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值