当前,当我创建生产者以发送记录时,例如由于某些原因,kafka不可用,生产者会无限期地发送相同的消息。例如,当我收到3次此错误后,如何停止产生消息:
Connection to node -1 could not be established. Broker may not be available.
我正在使用反应堆卡夫卡生产商:
@Bean
public KafkaSender<String, String> createSender() {
return KafkaSender.create(senderOptions());
}
private SenderOptions<String, String> senderOptions() {
Map<String, Object> props = new HashMap<>();
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaProperties.getBootstrapServers());
props.put(ProducerConfig.CLIENT_ID_CONFIG, kafkaProperties.getClientId());
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
props.put(ProducerConfig.RETRIES_CONFIG, kafkaProperties.getProducerRetries());
return SenderOptions.create(props);
}
然后使用它发送记录:
sender.send(Mono.just(SenderRecord.create(new ProducerRecord<>(topicName, null, message), message)))
.flatMap(result -> {
if (result.exception() != null) {
return Flux.just(ResponseEntity.badRequest()
.body(result.exception().getMessage()));
}
return Flux.just(ResponseEntity.ok().build());
})
.next();
答案 0 :(得分:0)
您可以使用circuit breaker pattern来解决此类问题,但是在应用此模式之前,请尝试查找根本原因,并且似乎ProducerConfig.RETRIES_CONFIG属性已被覆盖。
答案 1 :(得分:0)
恐怕clusterAndWaitTime = waitOnMetadata(record.topic(), record.partition(), maxBlockTimeMs);
不参与重试,并且默认情况下会迭代直到maxBlockTimeMs = 60000
为止。您可以通过ProducerConfig.MAX_BLOCK_MS_CONFIG
属性为生产者减少此选项:
public static final String MAX_BLOCK_MS_CONFIG = "max.block.ms";
private static final String MAX_BLOCK_MS_DOC = "The configuration controls how long <code>KafkaProducer.send()</code> and <code>KafkaProducer.partitionsFor()</code> will block."
+ "These methods can be blocked either because the buffer is full or metadata unavailable."
+ "Blocking in the user-supplied serializers or partitioner will not be counted against this timeout.";
更新
我们可以解决以下问题:
@PostMapping(path = "/v1/{topicName}")
public Mono<ResponseEntity<?>> postData(
@PathVariable("topicName") String topicName, String message) {
return sender.send(Mono.just(SenderRecord.create(new ProducerRecord<>(topicName, null, message), message)))
.flatMap(result -> {
if (result.exception() != null) {
sender.close();
return Flux.just(ResponseEntity.badRequest()
.body(result.exception().getMessage()));
}
return Flux.just(ResponseEntity.ok().build());
})
.next();
}
在出现错误的情况下,请注意sender.close();
。
我认为是时候对Reactor Kafka项目提出一个问题,以允许生产者因错误而关闭。
答案 2 :(得分:-1)
而不是专注于错误。解决问题-它没有连接到经纪人
您不会在撰写文件中覆盖此内容,因此您的应用正在尝试自行连接
bootstrap-servers: ${KAFKA_BOOTSTRAP_URL:localhost:9092}
在撰写yml中,您似乎忘记了此
rest-proxy:
environment:
KAFKA_BOOTSTRAP_URL: kafka:9092
或者,如果可能的话,您可以使用现有的Confluent REST Proxy泊坞窗映像,而不用重新发明轮子