Java 代理关闭时,Kafka producer正在丢失消息

Java 代理关闭时,Kafka producer正在丢失消息,java,apache-kafka,kafka-producer-api,Java,Apache Kafka,Kafka Producer Api,鉴于以下情况: 我在本地启动zookeeper和单个kafka代理,并创建测试主题,如kafka quickstart中所述: 然后,我运行一个简单的java程序,该程序每秒生成一条到测试主题的消息。一段时间后,我关闭了本地的kafka代理,看到制作人继续生成消息,它没有抛出任何异常。最后,我再次启动kafka broker,producer可以重新连接到broker并继续生成消息,但是,在kafka broker宕机期间生成的所有消息都丢失了。当检测到健康的卡夫卡经纪人时,制作人不会重播它们

鉴于以下情况:

我在本地启动zookeeper和单个kafka代理,并创建测试主题,如kafka quickstart中所述:

然后,我运行一个简单的java程序,该程序每秒生成一条到测试主题的消息。一段时间后,我关闭了本地的kafka代理,看到制作人继续生成消息,它没有抛出任何异常。最后,我再次启动kafka broker,producer可以重新连接到broker并继续生成消息,但是,在kafka broker宕机期间生成的所有消息都丢失了。当检测到健康的卡夫卡经纪人时,制作人不会重播它们

我怎样才能防止这种情况?我希望kafka producer在检测到kafka broker重新联机时重播这些消息。这是我的制作人配置:

props.put("bootstrap.servers", "localhost:9092");
props.put("acks", "all");
props.put("linger.ms", 0);
props.put("key.serializer", StringSerializer.class.getName());
props.put("value.serializer", StringSerializer.class.getName());

因为您只运行一个代理,所以当您的代理关闭时,恐怕您将无法存储消息

然而,奇怪的是,当你让你的经纪人下台时,你没有得到任何异常/警告/错误

我预计会出现更新元数据失败或消息过期错误,因为当生产者根据bootstrap.servers属性向提到的代理发送消息时,它会首先与zookeeper检查活动控制器或领导者和分区。因此,在您的情况下,因为您在独立模式下运行卡夫卡,并且当代理关闭时,制作人不应该收到领导信息并出错

请检查以下属性设置为什么:

request.timeout.ms
max.block.ms
和周围玩减少,可能是与这些价值观?然后检查结果

您可能希望尝试的另一个选项是以同步方式向Kafka发送消息,直到收到消息为止。下面是一个代码片段,可以从以下代码片段中获得帮助:

如果要模拟简单的阻塞调用,可以立即调用get方法:

byte[] key = "key".getBytes();
byte[] value = "value".getBytes();
ProducerRecord<byte[],byte[]> record = new ProducerRecord<byte[],byte[]>("my-topic", key, value)
producer.send(record).get();
在这种情况下,如果消息因任何原因未成功发送,kafka应引发异常


我希望这有帮助

Kafka Producer library内置了重试机制,但默认情况下已关闭。将重试生产者配置更改为大于0默认值的值以启用它。您还应该尝试retry.backoff.ms和request.timetout.ms,以便定制生产者重试

已启用重试的Kafka Producer配置示例:

retries=2147483647         //Integer.MAX_VALUE 
retry.backoff.ms=1000
request.timeout.ms=305000  //5 minutes
max.block.ms=2147483647    //Integer.MAX_VALUE 

您可以在中找到有关这些属性的更多信息。

是的,同步调用会引发异常,但我主要是想找到一个答案,说明当代理从崩溃中恢复时,为什么生产者不重新发送消息。重试队列中的消息是否保留在磁盘中?或者,如果生产者在重试期间崩溃,这些未发送的消息将丢失?