如何在Kafka消费者和生产者中实施恰好一次方案

时间:2019-01-11 12:39:14

标签: java apache-kafka

我正在尝试实施“恰好一次”方案。使用交易。

    properties.setProperty(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "127.0.0.1:9092");
    properties.setProperty(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
    properties.setProperty(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
    properties.setProperty(ProducerConfig.TRANSACTIONAL_ID_CONFIG, "prod-1");
    Producer<String, String> producer = new KafkaProducer<>(properties);

    producer.initTransactions();
    try {
        producer.beginTransaction();
        RecordMetadata rm = null;
        for (int i = 0; i < 100; i++) {
            String record = Arrays.asList(names).get(rand.nextInt(2));
            System.out.println(record);
            producer.send(newRandomTransaction(record));
        }
        producer.commitTransaction();
    } catch (ProducerFencedException e) {
        producer.close();
    } catch (KafkaException e) {
        producer.abortTransaction();
    }

    producer.close();

但是当我启动我的应用程序时,没有消息插入Kafka主题。

1 个答案:

答案 0 :(得分:0)

您不是在记录异常,也不在等待producer.send返回的Future的回调。

因此,您正在做“一劳永逸”的工作,因此尽可能快地发送记录,而不必担心它们是否真正到达了代理。

一种解决方案(假设没有错误发生)是您可以.send().get()对记录批处理执行阻止发送请求。一旦producer.close()被点击,它就应该完成并刷新交易