springboot集成kafka的相关配置及自定义

news/2024/10/18 5:40:21/

之前的文章末尾,简单的实现了springboot集成kafka,完成了简单的测试,今天我们来扩展一下相关内容。

首先详解一下配置文件的内容:

spring:kafka:# 指定 kafka 地址,我这里部署在的虚拟机,开发环境是Windows,kafkahost是虚拟机的地址, 若外网地址,注意修改为外网的IP( 集群部署需用逗号分隔)producer:bootstrap-servers: 124.223.205.125:9092# 发生错误后,消息重发的次数。retries: 3#当有多个消息需要被发送到同一个分区时,生产者会把它们放在同一个批次里。该参数指定了一个批次可以使用的内存大小,按照字节数计算。batch-size: 16384# 设置生产者内存缓冲区的大小。buffer-memory: 33554432# 指定消息key和消息体的序列化方式key-deserializer: org.apache.kafka.common.serialization.StringSerializervalue-deserializer: org.apache.kafka.common.serialization.StringSerializeracks: allproperties:# 自定义生产者拦截器interceptor.classes: com.volga.kafka.interceptor.ProducerPrefixInterceptorconsumer:enable-auto-commit: false #手动提交bootstrap-servers: ${spring.kafka.producer.bootstrap-servers}# 指定 group_idgroup-id: group_id# Kafka中没有初始偏移或如果当前偏移在服务器上不再存在时,默认区最新 ,有三个选项 【latest, earliest, none】auto-offset-reset: earliest# 指定消息key和消息体的序列化方式key-deserializer: org.apache.kafka.common.serialization.StringDeserializervalue-deserializer: org.apache.kafka.common.serialization.StringDeserializerproperties:# 自定义消费者拦截器interceptor.classes: com.volga.kafka.interceptor.ConsumerPrefixInterceptor# 默认主题topic: my-topiclistener:# 在侦听器容器中运行的线程数。concurrency: 5#listner负责ack,每调用一次,就立即commitack-mode: manual_immediatemissing-topics-fatal: falsetype: batch

以上的producer和consumer的相关配置也可以在java文件中实现:

如上图的实现,自己可以手动实现一下。

kafka内部自己实现分区、策略等一系列的逻辑,当然这些也可以自定义,这里有需要的可以自己研究一下,我这里就不需要了。

接下来,我介绍一个场景,是大家在实际的项目中可以用到。有这样一个场景,在项目中,我们搭建了kafka集群,然而在环境中,会有各种不同的消息,有一些消息不是我们需要的,有些消息是我们需要的,这时我们可以通过过滤器来进行控制和过滤。

在生产者端,我添加一个过滤器在消息前统一加上一个前缀。

 

@Slf4j
public class ProducerPrefixInterceptor implements ProducerInterceptor<String,String> {AtomicInteger success = new AtomicInteger(0);AtomicInteger fail = new AtomicInteger(0);@Overridepublic ProducerRecord<String, String> onSend(ProducerRecord<String, String> producerRecord) {// 消息统一添加前缀String modifyValue = "prefix-"+producerRecord.value();return new ProducerRecord<>(producerRecord.topic(), producerRecord.partition(), producerRecord.timestamp(), producerRecord.key(), modifyValue, producerRecord.headers());}@Overridepublic void onAcknowledgement(RecordMetadata recordMetadata, Exception e) {if (Objects.nonNull(recordMetadata)){success.incrementAndGet();}else {fail.incrementAndGet();}}@Overridepublic void close() {log.info("success:%d\nfail:%d\n",success.get(),fail.get());success.set(0);fail.set(0);}@Overridepublic void configure(Map<String, ?> map) {}
}

然后在消费者消费时,我遇到prefix前缀的消息时,就统一过滤掉,这不是我所需要的消息。

@Slf4j
public class ConsumerPrefixInterceptor implements ConsumerInterceptor<String,String> {/*** 过滤掉test开头的数据* @param consumerRecords* @return*/@Overridepublic ConsumerRecords<String, String> onConsume(ConsumerRecords<String, String> consumerRecords) {List<ConsumerRecord<String, String>> filterRecords = new ArrayList<>();Map<TopicPartition, List<ConsumerRecord<String, String>>> newRecords= new HashMap<>();Set<TopicPartition> partitions = consumerRecords.partitions();for(TopicPartition tp : partitions){List<ConsumerRecord<String, String>> records = consumerRecords.records(tp);for(ConsumerRecord<String, String> record: records){if(!record.value().startsWith("prefix")) {filterRecords.add(record);}}if(filterRecords.size() > 0){newRecords.put(tp, filterRecords);}}return new ConsumerRecords<>(newRecords);}@Overridepublic void onCommit(Map<TopicPartition, OffsetAndMetadata> map) {map.forEach((k,v) -> log.info("tp:%s--offset:%s\n",k,v));}@Overridepublic void close() {}@Overridepublic void configure(Map<String, ?> map) {}
}

相关的配置在上述的配置文件中也已经列出了,也可以在代码中加以配置。

props.put("properties.interceptor.classes","com.volga.kafka.interceptor.ProducerPrefixInterceptor");

这样就能实现过滤不需要的消息了。

翻看源码中,生产端主要是KafkaProducer<k,v>这个类中KafkaProducer方法:

消费端这边是对应的:KafkaConsumer<k,v>,这个类中KafkaConsumer方法:

源码里kafka实现的配置逻辑大家可以仔细研究一下。

我是空谷有来人,谢谢支持! 

 


http://www.ppmy.cn/news/55552.html

相关文章

PCL点云库(4) — console模块

目录 4.1 time时间打印 4.2 print 4.3 parse ◆ find_switch() ◆ find_argument() ◆ parse() ◆ parse_2x_arguments() ◆ parse_3x_arguments() ◆ parse_x_arguments() ◆ parse_multiple_arguments() ◆ parse_multiple_2x_arguments() ◆ parse_multiple…

阿里云服务器通用算力u1性能测评CPU处理器网络PPS

阿里云服务器u1通用算力型Universal实例高性价比&#xff0c;CPU采用Intel(R) Xeon(R) Platinum&#xff0c;主频是2.5 GHz&#xff0c;云服务器U1实例的基准vCPU算力与5代企业级实例持平&#xff0c;最高vCPU算力与6代企业级实例持平&#xff0c;提供2c-32c规格和1:1/2/4/8丰富…

Python小姿势 - Python学习笔记——类与对象

Python学习笔记——类与对象 类与对象是面向对象编程的两个基本概念。类是对象的抽象概念&#xff0c;对象是类的具体表现。 类是对一类事物的抽象&#xff0c;它是描述一类事物的模板&#xff0c;而对象是类的具体表现。对象是类的实例&#xff0c;类是对象的模板。 举个例子&…

使用ChatGPT生成了十种排序算法

前言 当前ChatGPT非常火爆&#xff0c;对于程序员来说&#xff0c;ChatGPT可以帮助编写很多有用的代码。比如&#xff1a;在算法的实现上&#xff0c;就可以替我们省很多事。所以&#xff0c;小试牛刀一下&#xff0c;看看ChatGPT生成了排序算法怎么样&#xff1f; 简介 排序…

Vue3通透教程【七】生命周期函数

文章目录 🌟 写在前面🌟 生命周期钩子函数🌟 组合式API生命周期🌟 写在最后🌟 写在前面 专栏介绍: 凉哥作为 Vue 的忠实 粉丝输出过大量的 Vue 文章,应粉丝要求开始更新 Vue3 的相关技术文章,Vue 框架目前的地位大家应该都晓得,所谓三大框架使用人数最多,公司选…

Python中“is”和“==”的区别(避坑)

2.3 “is”和“”的区别 在Python编写代码时&#xff0c;经常会遇到需要判断2个对象是否相等的情况&#xff0c;这个时候一般就会想到使用is和&#xff0c;is和好像都可以用来判断对象是否相等&#xff0c;经常会傻傻分不清&#xff0c;但其实这其中还是有区别的。 不过在这之…

漏洞分析和利用

1 安全漏洞生命周期 在渗透测试流程中,核心内容是找出目标系统中存在的安全漏洞,并实施渗透攻击,从而进入到目标系统中。而这一过程最主要的底层基础是目标系统中存在的安全漏洞(Vulnerability)。安全漏洞指信息系统中存在的缺陷或不适当的配置,它们可使攻击者在未授权情况…

C语言从入门到精通第11天(数组的基本操作)

数组的基本操作 数组的概念一维数组二维数组 数组的概念 在程序设计中&#xff0c;为了方便处理数据把具有相同类型的若干变量按有序形式集合在一起&#xff0c;这些按序排列的同类数据元素的集合称为数组。 在C语言中&#xff0c;数组属于构造数据类型&#xff0c;一个数组可…