我正在使用Springs kafkaTemplate将消息发布到Kafka主题,现在,为了实现某种故障安全机制,我想重试一些可变的尝试次数(以防Kafka关闭或某些网络故障),如果在“ n”之后重试次数,应运行带有@Recover
注释的恢复方法。
以下是我的接口定义:
@Retryable(
value = {PartnerPortalException.class},
maxAttempts = 2,
backoff = @Backoff(delay = 100)
)
void sendMessage(BizWebKafkaTopicMessage message) throws PartnerPortalException;
@Recover
void recoverFromSendMessageFailure(PartnerPortalException ex, BizWebKafkaTopicMessage message);
还org.springframework.kafka.core.KafkaTemplate#send()方法返回ListenableFuture,我可以在其中进行回调(成功和失败)。
界面的实现
@Override
public void sendMessage(BizWebKafkaTopicMessage message) {
LOGGER.debug("Publishing Message : {} to Kafka Topic : {} from {}#sendMessage ", message, topicName, CLASS_NAME);
ListenableFuture<SendResult<String, BizWebKafkaTopicMessage>> future = kafkaTemplate.send(topicName, message);
future.addCallback(new ListenableFutureCallback<>() {
@Override
public void onFailure(Throwable ex) {
LOGGER.error("Unable to publish message : {} to topic : [{}] due to : {} from {}#sendMessage() ", message, topicName, ex.getMessage(), CLASS_NAME);
// TODO Implement Retrying publishing of messages to kafka-topic.
throw new PartnerPortalException(HttpStatus.INTERNAL_SERVER_ERROR.toString(), ERROR_PUBLISHING_MESSAGE_TO_KAFKA, (Exception) ex);
}
@Override
public void onSuccess(SendResult<String, BizWebKafkaTopicMessage> sendResult) {
LOGGER.info("Message : {} published to topic : [{}] with offset = [{}] from {}#sendMessage() ", message, topicName, sendResult.getRecordMetadata().offset(), CLASS_NAME);
}
});
}
问题甚至发生在onFailure()
回调引发异常,@Retryable
不起作用而@Recover
也不起作用的情况下。
我怀疑这是因为嵌套的内部类。有没有办法将onFailure()回调引发的异常传播到@Retryable注释。
**注意**:为什么触发onFailure,我关闭了在后台运行的zookeeper和Kafka进程,以便测试我的@Retryable和@Recover故障安全机制。