如果异步发送到Kafka,我需要捕获异常。 Kafka制作人Api附带了一个函数send(ProducerRecord record,Callback callback)。但是,当我针对以下两种情况进行测试时:
问题:
那么仅针对特定异常才调用回调吗?
Kafka Client何时在异步发送时尝试连接到Kafka代理:在每批发送中还是定期发送?
注意:我还使用linger.ms设置25秒来批量发送记录。
public class ProducerDemo {
static KafkaProducer<String, String> producer;
public static void main(String[] args) throws IOException {
final Logger logger = LoggerFactory.getLogger(ProducerDemo.class);
Properties properties = new Properties();
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.ACKS_CONFIG, "1");
properties.setProperty(ProducerConfig.LINGER_MS_CONFIG, "30000");
producer = new KafkaProducer<String, String>(properties);
String topic = "first_topic";
for (int i = 0; i < 5; i++) {
String value = "hello world " + Integer.toString(i);
String key = "id_" + Integer.toString(i);
ProducerRecord<String, String> record = new ProducerRecord<String, String>(topic, key, value);
producer.send(record, new Callback() {
public void onCompletion(RecordMetadata recordMetadata, Exception e) {
//execute everytime a record is successfully sent or exception is thrown
if(e == null){
// No Exception
}else{
//Exception Handling
}
}
});
}
producer.close();
}
答案 0 :(得分:0)
对于第一个问题,这是答案。 根据apache kafka文档,在实现回调接口时,可以使用onCompletion方法捕获以下异常
https://kafka.apache.org/25/javadoc/org/apache/kafka/clients/producer/Callback.html
对于第二个问题,以下属性的组合控制何时发送记录,据我了解,同步或异步调用都相同。
linger.ms max.block.ms
答案 1 :(得分:0)
那么回调是否只针对特定异常调用?
是的,这就是它的工作原理。来自文档 (2.5.0):
* Fully non-blocking usage can make use of the {@link Callback} parameter to provide a callback that
* will be invoked when the request is complete.
注意重要的部分:请求完成时,这意味着生产者必须接受记录并将ProduceRequest发送给Kafka Broker。在不深入研究内部的情况下,这意味着必须存在代理元数据并且必须存在分区。
当涉及到正式规范时,您需要仔细查看 send()
的 Javadoc 以及 KafkaProducer 的 doSend
方法实现。在那里,您将看到在提交调用中可以抛出多个异常(而不是返回未来并调用回调),例如:
答案 2 :(得分:0)
您将收到针对不存在主题的警告,作为 KafkaProducer
提供的弹性机制。如果您等待更长时间(默认情况下应为 60 秒),最终将调用回调:
这是我的片段:
因此,当出现问题并且异步发送不成功时,它将最终失败并导致未来失败或/和回调异常。
如果您不是以事务方式运行它,则仍然可能意味着批处理中的某些消息已找到到达代理的方式,而其他消息则没有。
如果每条发送到 Kafka 的消息都需要对上游系统(如 http 摄取接口等)进行阻塞式确认,这肯定会成为一个问题。做到这一点的唯一方法是使用未来的 get
阻止每条消息,如 documentation 中所述:
总的来说,我注意到很多与 KafkaProducer 交付语义和保证相关的问题。绝对可以更好地记录它。
还有一件事,因为你提到了linger.ms:
<块引用>请注意,到达时间相近的记录通常会 即使与 linger.ms=0 一起批处理,因此在重负载下批处理将 无论延迟配置如何,都会发生