所以我有一个如下所示的SpringBoot端点控制器:
@RequestMapping(value = "/post", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public Response post(@Valid @RequestBody Message message) throws FailedToPostException {
message.setRecieveTime(System.currentTimeMillis());
return this.service.post(message);
}
帖子功能:
public Response post(Message message) throws FailedToPostException{
ListenableFuture<SendResult<String, Message>> future = kafkaTemplate.send("topicName", message);
future.addCallback(new ListenableFutureCallback<SendResult<String, Message>>() {
@Override
public void onSuccess(SendResult<String, Message> result) {
LOGGER.info("Post Finished. '{}' with offset: {}", message,
result.getRecordMetadata().offset());
}
@Override
public void onFailure(Throwable ex) {
LOGGER.error("Message Post Failed. '{}'", message, ex);
long nowMillis = System.currentTimeMillis();
int diffSeconds = (int) ((nowMillis - message.getRecieveTime()) / 1000);
if (diffSeconds >= 10) {
LOGGER.debug("timeout sending message to Kafka, aborting.");
return;
}
else {
post(message);
}
}
});
LOGGER.debug("D: " + Utils.getMetricValue("buffer-available-bytes", kafkaTemplate));
return new Response("Message Posted");
}
现在您可以看到,我们正在尝试确保,如果kafkaTemplate.send
失败,我们将再次递归调用post(message)
最多10秒,直到生产者内存缓冲区清除并且消息通过。
问题是:
旁注:我仍然没有使用kafkaTemplate.metrics()的buffer-available-bytes
属性,我打算用它来减少这个问题的可能性,但是在某些竞争条件的情况下仍然需要处理上面的问题
答案 0 :(得分:1)
有几种方法可以做到这一点,但我真的很喜欢Spring Retry
来解决这类问题。这里有一些伪代码,但是如果你需要更多关于如何做的细节,我可以让事情更明确:
@Retryable(maxAttempts = 10, value = KafkaSendException.class)
public Response post(Message message) throws FailedToPostException{
ListenableFuture<SendResult<String, Message>> future = kafkaTemplate.send("topicName", message);
try {
future.get(1. TimeUnit.SECONDS);
} catch(SomeException ex) {
LOGGER.error("Message Post Failed. '{}'", ex.getCause().getMessage(), ex);
throw ex;
}
LOGGER.info("Post Finished. '{}' with offset: {}", message,
result.getRecordMetadata().offset());
}
在没有递归的情况下有效地做同样的事情。我不建议递归代码以进行错误处理。
控制器应该能够按照实际的KafkaSendException
按下@ExceptionHandler
。{/ p>