简体   繁体   English

如何通过KafkaConsumer可靠地获取所有kafka主题消息

[英]How to reliably get all kafka topic messages via KafkaConsumer

The getMessages() method below sometimes gets all messages for a kafka topic. 下面的getMessages()方法有时会获取有关kafka主题的所有消息。 This code is executed in a web application on page load. 在页面加载时,此代码在Web应用程序中执行。 Sometimes no messages come back and sometimes all messages come back. 有时没有消息返回,有时所有消息都返回。

Is there a way to set properties and/or change the code so that all messages come back every time? 有没有办法设置属性和/或更改代码,以便所有消息每次都返回?

public List<String> getMessages() {
    List<String> messages = new ArrayList<>();
    try {
        ConnectionKafka connection = ConstantsHome.connectionManager.getConnectionDef(getGuid(), ConnectionKafka.class);
        Properties props = new Properties();
        props.put("bootstrap.servers", connection.getProps().get("bootstrapServers"));
        props.put("group.id", getName());
        props.put("auto.offset.reset", "earliest");
        props.put("enable.auto.commit", "true");
        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);
        consumer.subscribe(Collections.singleton(getName()));
        consumer.poll(0);
        consumer.seekToBeginning(consumer.assignment());
        ConsumerRecords<String, String> records = consumer.poll(0);
        for (ConsumerRecord<String, String> record : records) {
            messages.add(
                String.format("offset = %d, key = %s, value = %s%n", record.offset(), record.key(), record.value())
            );
        }
        consumer.close(0, TimeUnit.MILLISECONDS);
    } catch (Exception e) {
        Utils.writeToLog(e, getClass().getName(), "", IErrorManager.ERROR);
    }
    Collections.sort(messages, new Comparator<String>() {
        @Override
        public int compare(String o1, String o2) {
            return Integer.valueOf(o1.substring("offset = ".length(), o1.indexOf(","))) -
            Integer.valueOf(o2.substring("offset = ".length(), o2.indexOf(",")));
        }
    });
    return messages;
}

If your expectation is get all the messages for each call, you should be setting the following propertly 如果期望得到每个呼叫的所有消息,则应适当设置以下内容

enable.auto.commit = false

The other option is create a dynamic group ID for each iteration, I would avoid this option considering that the groups metadata is stored in the kafka side. 另一个选项是为每次迭代创建一个动态组ID,考虑到组元数据存储在kafka端,我会避免使用此选项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM