尝试按照互联网上的说明来实现kafka异步生成。这是我的制作人的样子:
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;
public void asynSend(String topic, Integer partition, String message) {
ProducerRecord<Object, Object> data = new ProducerRecord<>(topic, partition,null, message);
producer.send(data, new DefaultProducerCallback());
}
private static class DefaultProducerCallback implements Callback {
@Override
public void onCompletion(RecordMetadata recordMetadata, Exception e) {
if (e != null) {
logger.error("Asynchronous produce failed");
}
}
}
然后在这样的for循环中产生:
for (int i = 0; i < 5000; i++) {
int partition = i % 2;
FsProducerFactory.getInstance().asynSend(topic, partition,i + "th message to partition " + partition);
}
但是,某些消息可能会丢失。如下所示,从4508到4999的消息未传递。
我发现原因可能是生产者进程关闭,并且当时未发送的所有缓存消息都将丢失。 在for循环之后添加此行将解决此问题:
producer.flush();
但是,我不确定这是否是一个吸引人的解决方案,因为我注意到有人提到同花顺将使异步以某种方式发送同步,任何人都可以解释或帮助我改进它吗?
答案 0 :(得分:0)
在Kafka - The definitive Guide
书中,有一个示例,说明了一个与您编写代码完全相同的异步生产者。它与send
一起使用Callback
。
在discussion中这样写:
在退出之前添加
flush()
将使客户端等待任何未完成的消息传递到代理(这将是queue.buffering.max.ms
左右,外加延迟)。 如果在每个flush()
调用之后添加produce()
,则实际上是在实现同步生成器。
但是如果您在for
循环之后 这样做,它将不再是同步的,而是异步的。
您还可以做的是将Producer配置中的acks
设置为all
。这样,在主题的复制设置为大于1的情况下,您将有更多保证成功生成消息。