目录
说明
总结一下大家问的最多的一个问题
终极方法
思路
实现
代码
首页 Java java教程 springboot+kafka中@KafkaListener动态指定多个topic怎么实现

springboot+kafka中@KafkaListener动态指定多个topic怎么实现

May 20, 2023 pm 08:58 PM
springboot kafka @kafkalistener

说明

本项目为springboot+kafak的整合项目,故其用了springboot中对kafak的消费注解@KafkaListener

首先,application.properties中配置用逗号隔开的多个topic。

springboot+kafka中@KafkaListener动态指定多个topic怎么实现

方法:利用Spring的SpEl表达式,将topics 配置为:@KafkaListener(topics = “#{’${topics}’.split(’,’)}”)

springboot+kafka中@KafkaListener动态指定多个topic怎么实现

运行程序,console打印的效果如下:

springboot+kafka中@KafkaListener动态指定多个topic怎么实现

因为只开了一条消费者线程,所以所有的topic和分区都分配给这条线程。

如果你想开多条消费者线程去消费这些topic,添加@KafkaListener注解的参数concurrency的值为自己想要的消费者个数即可(注意,消费者数要小于等于你开的所有topic的分区数总和)

springboot+kafka中@KafkaListener动态指定多个topic怎么实现

运行程序,console打印的效果如下:

springboot+kafka中@KafkaListener动态指定多个topic怎么实现

总结一下大家问的最多的一个问题

如何在程序运行的过程中,改变topic,消费者能够消费修改后的topic?

ans: 经过尝试,使用@KafkaListener注解实现不了此需求,在程序启动的时候,程序就会根据@KafkaListener的注解信息初始化好消费者去消费指定好的topic。如果在程序运行的过程中,修改topic,不会让此消费者修改消费者的配置再重新订阅topic的。

不过我们可以有个折中的办法,就是利用@KafkaListener的topicPattern参数来进行topic匹配。

终极方法

思路

使用 Kafka 原生客户端依赖,手动初始化消费者并启动消费者线程,而非使用 @KafkaListener。

在消费者线程中,每次循环都从配置、数据库或者其他配置源获取最新的topic信息,与之前的topic比较,如果发生变化,重新订阅topic或者初始化消费者。

实现

加入kafka客户端依赖(本次测试服务端kafka版本:2.12-2.4.0)

<dependency>
	<groupId>org.apache.kafka</groupId>
	<artifactId>kafka-clients</artifactId>
	<version>2.3.0</version>
</dependency>
登录后复制

代码

@Service
@Slf4j
public class KafkaConsumers implements InitializingBean {

    /**
     * 消费者
     */
    private static KafkaConsumer<String, String> consumer;
    /**
     * topic
     */
    private List<String> topicList;

    public static String getNewTopic() {
        try {
            return org.apache.commons.io.FileUtils.readLines(new File("D:/topic.txt"), "utf-8").get(0);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 初始化消费者(配置写死是为了快速测试,请大家使用配置文件)
     *
     * @param topicList
     * @return
     */
    public KafkaConsumer<String, String> getInitConsumer(List<String> topicList) {
        //配置信息
        Properties props = new Properties();
        //kafka服务器地址
        props.put("bootstrap.servers", "192.168.9.185:9092");
        //必须指定消费者组
        props.put("group.id", "haha");
        //设置数据key和value的序列化处理类
        props.put("key.deserializer", StringDeserializer.class);
        props.put("value.deserializer", StringDeserializer.class);
        //创建消息者实例
        KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
        //订阅topic的消息
        consumer.subscribe(topicList);
        return consumer;
    }

    /**
     * 开启消费者线程
     * 异常请自己根据需求自己处理
     */
    @Override
    public void afterPropertiesSet() {
        // 初始化topic
        topicList = Splitter.on(",").splitToList(Objects.requireNonNull(getNewTopic()));
        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(topicList)) {
            consumer = getInitConsumer(topicList);
            // 开启一个消费者线程
            new Thread(() -> {
                while (true) {
                    // 模拟从配置源中获取最新的topic(字符串,逗号隔开)
                    final List<String> newTopic = Splitter.on(",").splitToList(Objects.requireNonNull(getNewTopic()));
                    // 如果topic发生变化
                    if (!topicList.equals(newTopic)) {
                        log.info("topic 发生变化:newTopic:{},oldTopic:{}-------------------------", newTopic, topicList);
                        // method one:重新订阅topic:
                        topicList = newTopic;
                        consumer.subscribe(newTopic);
                        // method two:关闭原来的消费者,重新初始化一个消费者
                        //consumer.close();
                        //topicList = newTopic;
                        //consumer = getInitConsumer(newTopic);
                        continue;
                    }
                    ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));
                    for (ConsumerRecord<String, String> record : records) {
                        System.out.println("key:" + record.key() + "" + ",value:" + record.value());
                    }
                }
            }).start();
        }
    }
}
登录后复制

说一下第72行代码:

ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));
登录后复制

上面这行代码表示:在100ms内等待Kafka的broker返回数据.超市参数指定poll在多久之后可以返回,不管有没有可用的数据都要返回。

在修改topic后,必须等到此次poll拉取的消息处理完,while(true)循环的时候检测topic发生变化,才能重新订阅topic.

poll()方法一次拉取得消息数默认为:500,如下图,kafka客户端源码中设置的。

springboot+kafka中@KafkaListener动态指定多个topic怎么实现

如果想自定义此配置,可在初始化消费者时加入

springboot+kafka中@KafkaListener动态指定多个topic怎么实现

运行结果(测试的topic中都无数据)

springboot+kafka中@KafkaListener动态指定多个topic怎么实现

注意:KafkaConsumer是线程不安全的,不要用一个KafkaConsumer实例开启多个消费者,要开启多个消费者,需要new 多个KafkaConsumer实例。

以上是springboot+kafka中@KafkaListener动态指定多个topic怎么实现的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它们
4 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

如何使用PHP和Kafka实现实时股票分析 如何使用PHP和Kafka实现实时股票分析 Jun 28, 2023 am 10:04 AM

随着互联网和科技的发展,数字化投资已成为人们越来越关注的话题。很多投资者不断探索和研究投资策略,希望能够获得更高的投资回报率。股票交易中,实时的股票分析对决策非常重要,其中使用Kafka实时消息队列和PHP技术实现更是一种高效且实用的手段。一、Kafka介绍Kafka是由LinkedIn公司开发的一个高吞吐量的分布式发布、订阅消息系统。Kafka的主要特点是

SpringBoot与SpringMVC的比较及差别分析 SpringBoot与SpringMVC的比较及差别分析 Dec 29, 2023 am 11:02 AM

SpringBoot和SpringMVC都是Java开发中常用的框架,但它们之间有一些明显的差异。本文将探究这两个框架的特点和用途,并对它们的差异进行比较。首先,我们来了解一下SpringBoot。SpringBoot是由Pivotal团队开发的,它旨在简化基于Spring框架的应用程序的创建和部署。它提供了一种快速、轻量级的方式来构建独立的、可执行

如何利用React和Apache Kafka构建实时数据处理应用 如何利用React和Apache Kafka构建实时数据处理应用 Sep 27, 2023 pm 02:25 PM

如何利用React和ApacheKafka构建实时数据处理应用引言:随着大数据与实时数据处理的兴起,构建实时数据处理应用成为了很多开发者的追求。React作为一个流行的前端框架,与ApacheKafka作为一个高性能的分布式消息传递系统的结合,可以帮助我们搭建实时数据处理应用。本文将介绍如何利用React和ApacheKafka构建实时数据处理应用,并

SpringBoot+Dubbo+Nacos 开发实战教程 SpringBoot+Dubbo+Nacos 开发实战教程 Aug 15, 2023 pm 04:49 PM

本文来写个详细的例子来说下dubbo+nacos+Spring Boot开发实战。本文不会讲述太多的理论的知识,会写一个最简单的例子来说明dubbo如何与nacos整合,快速搭建开发环境。

五种选择的可视化工具,用于探索Kafka 五种选择的可视化工具,用于探索Kafka Feb 01, 2024 am 08:03 AM

Kafka可视化工具的五种选择ApacheKafka是一个分布式流处理平台,能够处理大量实时数据。它广泛用于构建实时数据管道、消息队列和事件驱动的应用程序。Kafka的可视化工具可以帮助用户监控和管理Kafka集群,并更好地理解Kafka数据流。以下是对五种流行的Kafka可视化工具的介绍:ConfluentControlCenterConfluent

kafka可视化工具对比分析:如何选择最合适的工具? kafka可视化工具对比分析:如何选择最合适的工具? Jan 05, 2024 pm 12:15 PM

如何选择合适的Kafka可视化工具?五款工具对比分析引言:Kafka是一种高性能、高吞吐量的分布式消息队列系统,被广泛应用于大数据领域。随着Kafka的流行,越来越多的企业和开发者需要一个可视化工具来方便地监控和管理Kafka集群。本文将介绍五款常用的Kafka可视化工具,并对比它们的特点和功能,帮助读者选择适合自己需求的工具。一、KafkaManager

如何在 Rocky Linux 上安装 Apache Kafka? 如何在 Rocky Linux 上安装 Apache Kafka? Mar 01, 2024 pm 10:37 PM

在RockyLinux上安装ApacheKafka可以按照以下步骤进行操作:更新系统:首先,确保你的RockyLinux系统是最新的,执行以下命令更新系统软件包:sudoyumupdate安装Java:ApacheKafka依赖于Java,因此需要先安装JavaDevelopmentKit(JDK)。可以通过以下命令安装OpenJDK:sudoyuminstalljava-1.8.0-openjdk-devel下载和解压:访问ApacheKafka官方网站()下载最新的二进制包。选择一个稳定版本

go-zero与Kafka+Avro的实践:构建高性能的交互式数据处理系统 go-zero与Kafka+Avro的实践:构建高性能的交互式数据处理系统 Jun 23, 2023 am 09:04 AM

近年来,随着大数据的兴起和活跃的开源社区,越来越多的企业开始寻找高性能的交互式数据处理系统来满足日益增长的数据需求。在这场技术升级的浪潮中,go-zero和Kafka+Avro被越来越多的企业所关注和采用。go-zero是一款基于Golang语言开发的微服务框架,具有高性能、易用、易扩展、易维护等特点,旨在帮助企业快速构建高效的微服务应用系统。它的快速成长得

See all articles