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提交导致冲突,应该为不同消费者实例配置不同的分组。

相关推荐
Jack_David3 小时前
Kafka批量消息发送
java·分布式·kafka
wanhengidc3 小时前
服务器托管对企业的作用
大数据·运维·服务器·分布式·智能手机
Code知行合壹3 小时前
Spark使用总结
大数据·分布式·spark
Swift社区3 小时前
分布式能力不是功能,而是一种架构约束
分布式·架构
0xDevNull4 小时前
Apache Kafka 完全指南
分布式·kafka
zb200641205 小时前
RabbitMQ 客户端 连接、发送、接收处理消息
分布式·rabbitmq·ruby
半桶水专家6 小时前
Kafka JMX详解
分布式·kafka
渔民小镇6 小时前
告别 if-else 地狱 —— JSR380 参数验证在 ionet 中的应用
java·服务器·分布式·游戏
智慧科技的海洋6 小时前
微电网智慧平台:破解能源困局的分布式能源革命
分布式·能源
深蓝轨迹6 小时前
Redisson 分布式锁复习总结
分布式