部署期间,消息是否会在kafka生产者端丢失?

时间:2020-07-10 19:07:54

标签: java apache-kafka spring-kafka kafka-producer-api

我们正面临一个特殊的问题,看到我们向Kafka生成消息时,有时在用户端找不到该消息。我们尝试进一步调试它,并启用onSuccess()和onFailure()回调。我们得到的主要问题是-

org.springframework.kafka.core.KafkaProducerException: Failed to send; nested exception is org.apache.kafka.common.errors.NotLeaderForPartitionException: This server is not the leader for that topic-partition.

为解决此问题,我们将重试次数增加到10次,这几乎可以完全解决该问题。

但是,我们发现3个msgs(每个消息在不同的时间)都没有onSuccess()或onFailure()回调。可以这么说,它只是在交流中迷路了!

现在,这发生在撤消应用程序以进行重新部署之前。我从Kafka Producer Config获悉,默认的批处理大小为16KB,它在实际将消息发送给代理之前会等待该批处理被填充(为简化起见,我故意考虑了linger.ms)。

我的问题是,当系统被强制关闭以进行部署时,卡夫卡批处理中的所有消息是否会丢失?如果是,我们如何解决这个问题?

请在这里帮助我,因为这是我们在生产中面临的问题。

非常感谢!

1 个答案:

答案 0 :(得分:1)

如果您正在使用批处理,并且服务器死机(kill -9,System.exit()或电源故障),您可能会丢失消息。

如果您正在使用Spring Boot并执行有序关闭(Ctrl-C)或以其他方式关闭Spring ApplicationContext(例如,使用ShutDownHook),则不应丢失任何内容,因为生产者将在上下文关闭期间关闭,从而强制执行推送部分批次。

如果挂起的发送无法完成,您应该看到一条日志消息:

log.info("Proceeding to force close the producer since pending requests could not be completed " +
                "within timeout {} ms.", timeoutMs);

您可以在KafkaProducer中看到close()代码。