如何使用带回调的send()方法返回元数据?

时间:2018-03-29 00:14:03

标签: java kafka-producer-api confluent-kafka

我想像这样使用Kafka Producer send()的回调方法:

RecordMetadata recordmetadata = kafkaProducer.send(new ProducerRecord<>(topic,
                null, timestamp, key, message), this::onCompletion);

private RecordMetadata onCompletion(RecordMetadata metadata, Exception exception) {
    if (exception == null) {
        return metadata;
    } else {
        return null;
    }
}

但是我有send()方法返回的元数据或null方法返回的onCompletion(因为调用send()的方法取决于它)。

如何将send()返回元数据或null与回调方法结合使用?

2 个答案:

答案 0 :(得分:0)

文档指出send是异步的,一旦记录存储在等待发送的记录缓冲区中,该方法将立即返回。为了使它能够按你的意愿工作,你必须为它实现自己的解决方案,例如使用全局标志:

private RecordMetadata recordMetadata;
private boolean onCompletetionExecuted = false;

kafkaProducer.send(new ProducerRecord<>(topic,
                null, timestamp, key, auditorMessage), this::onCompletion);
while (!onCompletetionExecuted) {
    // waiting, would be good to have a fixed timeout
}
// after this point the value of recordMetadata is the one returned by onCompletion

private void onCompletion(RecordMetadata metadata, Exception exception) {
    if (exception == null) {
        recordMetadata = metadata;
    } else {
        recordMetadata = null;
    }
    onCompletetionExecuted = true;
}

这远非优雅,但它可以完成这项工作。

答案 1 :(得分:0)

请记住send()在异步模式下工作,因此onCompletion将在send()调用创建的新线程中执行。

如果需要元数据。您应该这样做。

RecordMetadata recordmetadata = kafkaProducer.send(new ProducerRecord<>(topic,
            null, timestamp, key, message), this::onCompletion).get();

请记住,使用此方法,发送的呼叫将在继续之前等待写入/超时。