kafka动态监听主题

简单版本

java 复制代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.ConsumerFactory;
import org.springframework.kafka.listener.ConcurrentMessageListenerContainer;
import org.springframework.kafka.listener.ContainerProperties;
import org.springframework.kafka.listener.MessageListener;
import org.springframework.stereotype.Service;

@Service
public class DynamicKafkaListenerService {

    @Autowired
    private ConsumerFactory<String, String> consumerFactory;

    public void registerListener(String topic) {
        ContainerProperties containerProperties = new ContainerProperties(topic);
        containerProperties.setMessageListener((MessageListener<String, String>) record -> {
            System.out.println(Thread.currentThread().getName() + " 主题 " + topic + " 收到消息: " + record.value());
        });
        ConcurrentMessageListenerContainer<String, String> container = new ConcurrentMessageListenerContainer<>(consumerFactory, containerProperties);
        container.setBeanName(topic + "-listener");
        container.start();
    }
}

手动ack版本

java 复制代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.ConsumerFactory;
import org.springframework.kafka.listener.AcknowledgingMessageListener;
import org.springframework.kafka.listener.ConcurrentMessageListenerContainer;
import org.springframework.kafka.listener.ContainerProperties;
import org.springframework.stereotype.Service;

@Service
public class DynamicKafkaListenerService {

    @Autowired
    private ConsumerFactory<String, String> consumerFactory;

    public void registerListener(String topic) {
        ContainerProperties containerProperties = new ContainerProperties(topic);
        // 设置消息监听器为 AcknowledgingMessageListener
        containerProperties.setMessageListener((AcknowledgingMessageListener<String, String>) (record, ack) -> {
            try {
                System.out.println(Thread.currentThread().getName() + " 主题 " + topic + " 收到消息: " + record.value());
                // 模拟消息处理逻辑
                // 处理完成后手动确认消息
                if (ack != null) {
                    ack.acknowledge();
                }
            } catch (Exception e) {
                // 处理异常情况,例如记录日志或重试等
                System.err.println("消息处理失败: " + e.getMessage());
            }
        });
        // 设置手动确认模式
        containerProperties.setAckMode(ContainerProperties.AckMode.MANUAL_IMMEDIATE);
        ConcurrentMessageListenerContainer<String, String> container = new ConcurrentMessageListenerContainer<>(consumerFactory, containerProperties);
        container.setBeanName(topic + "-listener");
        container.start();
    }
}

批量处理版本

java 复制代码
    @Autowired
    private ConsumerFactory<String, String> consumerFactory;

    public void registerListener(String topic) {
        ContainerProperties containerProperties = new ContainerProperties(topic);
        // 设置手动确认模式
        containerProperties.setAckMode(ContainerProperties.AckMode.MANUAL_IMMEDIATE);
        // 设置批量消息监听器
        containerProperties.setMessageListener((BatchAcknowledgingMessageListener<String, String>) (records, ack) -> {
            try {
                for (ConsumerRecord<String, String> record : records) {
                    System.out.println(Thread.currentThread().getName() + " 主题 " + topic + " 收到消息: " + record.value());
                }
                // 模拟消息处理逻辑
                // 处理完成后手动批量确认消息
                ack.acknowledge();
            } catch (Exception e) {
                // 处理异常情况,例如记录日志或重试等
                System.err.println("消息处理失败: " + e.getMessage());
            }
        });
        ConcurrentMessageListenerContainer<String, String> container = new ConcurrentMessageListenerContainer<>(consumerFactory, containerProperties);
        container.setBeanName(topic + "-listener");
        container.start();
    }

可关闭版本

java 复制代码
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.ConsumerFactory;
import org.springframework.kafka.listener.BatchAcknowledgingMessageListener;
import org.springframework.kafka.listener.ConcurrentMessageListenerContainer;
import org.springframework.kafka.listener.ContainerProperties;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

@Service
public class DynamicKafkaListenerService {


    @Autowired
    private ConsumerFactory<String, String> consumerFactory;

    // 用于保存每个主题对应的监听器容器
    private final Map<String, ConcurrentMessageListenerContainer<String, String>> containerMap = new HashMap<>();

    /**
     * 开启一个监听
     */
    public void registerListener(String topic) {
        ContainerProperties containerProperties = new ContainerProperties(topic);
        // 设置手动确认模式
        containerProperties.setAckMode(ContainerProperties.AckMode.MANUAL_IMMEDIATE);
        // 设置批量消息监听器
        containerProperties.setMessageListener((BatchAcknowledgingMessageListener<String, String>) (records, ack) -> {
            try {
                for (ConsumerRecord<String, String> record : records) {
                    System.out.println(Thread.currentThread().getName() + " 主题 " + topic + " 收到消息: " + record.value());
                }
                // 模拟消息处理逻辑
                // 处理完成后手动批量确认消息
                ack.acknowledge();
            } catch (Exception e) {
                // 处理异常情况,例如记录日志或重试等
                System.err.println("消息处理失败: " + e.getMessage());
            }
        });
        ConcurrentMessageListenerContainer<String, String> container = new ConcurrentMessageListenerContainer<>(consumerFactory, containerProperties);
        container.setBeanName(topic + "-listener");
        container.start();
        // 将监听器容器保存到 map 中
        containerMap.put(topic, container);
    }

    /**
     * 关闭一个监听
     */
    public void stopListener(String topic) {
        ConcurrentMessageListenerContainer<String, String> container = containerMap.get(topic);
        if (container != null && container.isRunning()) {
            container.stop();
            // 从 map 中移除已停止的监听器容器
            containerMap.remove(topic);
        }
    }
}

调用添加监听

java 复制代码
    /**
     * 配置详情
     */
    @GetMapping("/getModelZdyConfInfo")
    public String getModelZdyConfInfo(String topic) {
        dynamicKafkaListenerService.registerListener(topic);
        return "添加" + topic + "监听成功";
    }
相关推荐
睡醒的土豆2 小时前
解决 Kafka 管理工具中文乱码问题
分布式·kafka
SuniaWang5 小时前
《Spring AI + 大模型全栈实战》学习手册系列· 专题二:《Milvus 向量数据库:从零开始搭建 RAG 系统的核心组件》
java·人工智能·分布式·后端·spring·架构·typescript
Hui Baby5 小时前
TIDB分布式数据库提交设想
数据库·分布式·tidb
⑩-5 小时前
RabbitMQ 架构和工作原理?RabbitMQ 延迟队列如何实现?
java·分布式·架构·rabbitmq
国冶机电安装5 小时前
分布式控制系统(DCS)安装:从方案设计到投运验收的完整指南
分布式
飞Link6 小时前
告别 ROS 的臃肿:用 ZeroMQ 构建极速具身智能分布式大脑(附 Python 实战)
开发语言·分布式·python
殷紫川7 小时前
击穿 Kafka 高可用核心:分区副本、ISR 机制与底层原理全链路拆解
架构·kafka
会算数的⑨7 小时前
演进——从查日志到 AI 自治,企业监控体系的变迁
人工智能·分布式·后端·微服务·云原生
岁岁种桃花儿8 小时前
Flink从入门到上天系列第二十五篇:Flink和Kafka连接时的精准一次性
大数据·flink·kafka
一叶飘零_sweeeet8 小时前
分布式权限体系破局:统一认证授权与 OAuth2.0 全链路架构落地实战
分布式·架构