Kafka应用Demo:指派分区订阅消息消费

环境准备

 Kafka环境搭建和生产者样例代码与《Kafka应用Demo:按主题订阅消费消息》相同。

消费者代码样例

java 复制代码
public class KafkaConsumerService {
    private static final Logger LOGGER = LoggerFactory.getLogger(KafkaConsumerService.class);
    private static final String NEO_TOPIC = "elon-topic";

    Properties properties = new Properties();
    private KafkaConsumer consumer = null;

    public KafkaConsumerService() {
        TopicPartition partition0 = new TopicPartition(NEO_TOPIC, 0);
        TopicPartition partition1 = new TopicPartition(NEO_TOPIC, 1);

        properties.put("bootstrap.servers","192.168.5.128:9092");  // 指定 Broker
        properties.put("group.id", "neo2");              // 指定消费组群 ID
        properties.put("max.poll.records", "1");
        properties.put("enable.auto.commit", "false");
        properties.put("key.deserializer", StringDeserializer.class); // 将 key 的字节数组转成 Java 对象
        properties.put("value.deserializer", StringDeserializer.class);  // 将 value 的字节数组转成 Java 对象

        consumer = new KafkaConsumer<String, String>(properties);
        List<TopicPartition> partitionList = new ArrayList<>();
        partitionList.add(partition1);
        partitionList.add(partition0);
        consumer.assign(partitionList);
        new Thread(this::receiveMessage).start();
    }

    public void receiveMessage() {
        try {
            while (true) {
                synchronized (this) {
                    ConsumerRecords<String,String> records = consumer.poll(Duration.ofMillis(Long.MAX_VALUE));
                    LOGGER.info("Fetch record num:{}", records.count());
                    for (ConsumerRecord<String,String> record: records) {
                        String info = String.format("[Topic: %s][Partition:%d][Offset:%d][Key:%s][Message:%s]",
                                record.topic(), record.partition(), record.offset(), record.key(), record.value());
                        LOGGER.info("Received:" + info);
                        Thread.sleep(10000);
                    }
                    consumer.commitSync();
                }
            }
        } catch (Exception e){

        } finally {
            consumer.close();
        }
    }
}

 样例代码中的consumer.assign(partitionList)绑定了主题下的0号分区和1号分区接收消息。指派分区的方式和按主题订阅的方式不能混用,也就是说一个消费者实例只能选择一种方式订阅。

分析

 如果我们同时启动两个conumer实例,指派订阅相同主题和相同分区的消息。可以看到这两个实例收到了相同的消息,哪怕这两个消费者配置了相同的分组,这一点是与按主题订阅消息不同的。

 根据官方指导文档的说法,如果使用assign绑定分区订阅消息,不同的消费者实例是相互独立的(编者注:相当于广播消息)。为了避免offset提交导致冲突,应该为不同消费者实例配置不同的分组。

相关推荐
heimeiyingwang8 小时前
【架构实战】线程池设计:高并发系统的资源管理艺术
分布式·架构
一个骇客8 小时前
分布式批处理:当你的单机脚本跑了一天一夜还没出结果
分布式·架构
小蒋学算法8 小时前
redis分布式锁实现
数据库·redis·分布式
珠***格8 小时前
四可装置核心技术:高精度采集、边缘计算、协议自适应
大数据·人工智能·分布式·能源·边缘计算
AI人工智能+电脑小能手9 小时前
【大白话说Java面试题 第97题】【Mysql篇】第27题:说说分库与分表的设计?
java·开发语言·数据库·分布式·mysql·算法
可乐ea9 小时前
【知识获取与分享社区项目 | 项目日记第 23 天】项目梳理下篇:高并发与最终一致性复盘:Redis、Kafka、Outbox、ES 与 RAG 如何协同
java·redis·mysql·elasticsearch·缓存·ai·kafka
小张小张爱学习9 小时前
分布式高频面试题
java·分布式
段一凡-华北理工大学10 小时前
工业领域的Hadoop架构学习~系列文章16:实时流处理架构 - 工业数据的实时动脉
大数据·数据仓库·hadoop·分布式·学习·架构·高炉炼铁
我是一颗柠檬10 小时前
【Java项目技术亮点】Outbox事件驱动模式:解决分布式事务的终极方案
java·开发语言·分布式·后端·中间件·kafka
珠***格11 小时前
边缘计算——“云-边-端”协同架构解析
大数据·人工智能·分布式·架构·能源·边缘计算