kafka使用高级api获取指定数量消息

本文介绍如何利用Kafka的高级API来获取指定数量的消息,对比低级API,高级API在某些场景下更易用。示例代码展示了在设定最大读取量和超时时间的情况下获取消息的方法。

kafka使用高级api获取指定数量消息,低级api更好用只不过还未调试通过,后期再跟上.

public Map<String, List<Object>> getMessages(long maxReads, long timeout,

            List<String> topics) {
        stop = false;
        kafkaConsumer = new KafkaConsumer<>(props);
        kafkaConsumer.subscribe(topics);
        Map<String, List<Object>> messages = new HashMap<>();
        for (String topic : topics) {
            messages.put(topic, new ArrayList<Object>());
        }
        Long counts = maxReads;
        ConsumerRecord<byte[], byte[]> record = null;
        ConsumerRecords<byte[], byte[]> records = null;
        try {
            while (!stop) {
                if (counts == 0)
                    break;
                records = kafkaConsumer.poll(timeout);
                if (records.count() == 0)
                    continue;
                counts -= records.count();
                // 出现消息过剩状况
                if (counts < 0) {
                    // 记录将要消费的offsets
                    Map<String, Map<Integer, Long>> commitMap = new HashMap<>();
                    Iterator<ConsumerRecord<byte[], byte[]>> itt = records
                            .iterator();
                    while (itt.hasNext()) {
                        record = itt.next();
                        if (commitMap.containsKey(record.topic())) {
                            if (!commitMap.get(record.topic()).containsKey(
                                    record.partition())) {
                                commitMap.get(record.topic()).put(
                                        record.partition(), record.offset());
                            } else
                                continue;
                        } else {
                            Map<Integer, Long> m = new HashMap<>();
                            m.put(record.partition(), record.offset());
                            commitMap.put(record.topic(), m);
                        }
                    }
                    Iterator<ConsumerRecord<byte[], byte[]>> it = records
                            .iterator();
                    for (int i = 0; i < counts + records.count(); i++) {
                        record = it.next();
                        commitMap.get(record.topic()).put(record.partition(),
                                record.offset() + 1);
                        messages.get(record.topic()).add(
                                kryo.deserialize(
                                        record.value(),
                                        TopicMapperUtil.getValueClass(
                                                record.topic(), mapper)));
                    }
                    Map<TopicPartition, OffsetAndMetadata> map = new HashMap<>();
                    TopicPartition partition = null;
                    OffsetAndMetadata offset = null;
                    for (Entry<String, Map<Integer, Long>> entry : commitMap
                            .entrySet()) {
                        for (Entry<Integer, Long> en : entry.getValue()
                                .entrySet()) {
                            partition = new TopicPartition(entry.getKey(),
                                    en.getKey());

                            offset = new OffsetAndMetadata(en.getValue());

                            //重置下一次poll的offset

                            kafkaConsumer.seek(partition, offset.offset());
                            map.put(partition, offset);
                        }

                    }
                    kafkaConsumer.commitSync(map);
                    break;
                }
                kafkaConsumer.commitSync();
                for (ConsumerRecord<byte[], byte[]> tmpRecord : records) {
                    messages.get(tmpRecord.topic()).add(
                            kryo.deserialize(
                                    tmpRecord.value(),
                                    TopicMapperUtil.getValueClass(
                                            tmpRecord.topic(), mapper)));
                }
            }
        } finally {
            kafkaConsumer.close();
            kafkaConsumer = null;
        }
        return messages;
    }
Kafka是一个分布式流处理平台,主要用于构建实数据管道和流应用程序。Kafka的消费者可以按照不同的策略来获取消息,比如最新的消息、最早的未处理消息等。如果你想指定消费两条数据,可以通过以下步骤在Kafka中实现: 1. 确定你想要消费的主题(Topic)以及对应的分区(Partition)。 2. 确定你想要消费的起始位置。如果你想要从最新消息开始消费,可以从最新的偏移量(Offset)开始;如果你想要从最早的消息开始消费,可以使用最早的偏移量。除此之外,你也可以指定一个具体的偏移量来开始消费。 3. 消费者启动后,可以设置一个简单的循环,持续从Kafka中拉取消息。通常在循环中会有一个条件判断,比如当消费的消息数量达到你想要的数量就退出循环。 使用Kafka高级API(如Kafka Streams或Kafka Consumer API)可以更方便地控制消费的起始位置和消费的数据量。以Kafka Consumer API为例,你可以通过`poll`方法来拉取一定数量消息,并在内部通过计数器来控制消费的消息数量。 示例代码(使用Kafka Consumer API): ```java Properties props = new Properties(); props.put("bootstrap.servers", "localhost:9092"); props.put("group.id", "test"); props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer"); props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer"); KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props); String topic = "your_topic"; consumer.subscribe(Arrays.asList(topic)); int targetNumOfRecords = 2; // 目标消费的消息数量 int recordsCount = 0; // 已消费的消息数量 try { while (recordsCount < targetNumOfRecords) { ConsumerRecords<String, String> records = consumer.poll(100); for (ConsumerRecord<String, String> record : records) { // 处理消息逻辑 System.out.printf("offset = %d, key = %s, value = %s%n", record.offset(), record.key(), record.value()); recordsCount++; } } } finally { consumer.close(); } ``` 在这个示例中,消费者会持续从Kafka拉取消息,并通过一个计数器`recordsCount`来记录已消费的消息数量,一旦达到指定的`targetNumOfRecords`,就会停止消费。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值