Spring-kafka內部封裝了可重試消費消息的語義,也就是可以設置爲當消費數據出現異常時,重試這個消息。而且可以設置重試達到多少次後,讓消息進入預定好的Topic。也就是死信隊列裏。
demo
@Component
@EnableScheduling
public class DemoListener {
private static final Logger logger = LoggerFactory.getLogger(DemoListener.class);
@Autowired
private ConsumerFactory consumerFactory;
@Autowired
private KafkaTemplate kafkaTemplate;
@Bean
public ConcurrentKafkaListenerContainerFactory containerFactory() {
ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory();
factory.setConsumerFactory(consumerFactory);
// 最大重試次數3次
factory.setErrorHandler(new SeekToCurrentErrorHandler(new DeadLetterPublishingRecoverer(kafkaTemplate), 3));
return factory;
}
@KafkaListener(id = "group", topics = "testTopic", containerFactory = "containerFactory")
public void listen(ConsumerRecord record, Acknowledgment ack) throws Exception {
Optional kafkaMessage = Optional.ofNullable(record.value());
if (!kafkaMessage.isPresent()) {
throw new Exception("監聽到的消息爲空值");
}
logger.info("topicID: " + record.topic());
logger.info("recordValue: " + record.value());
try {
/*業務邏輯*/
ack.acknowledge();
} catch (Exception e) {
throw new Exception("消息異常,進入死信隊列...");
}
}
@KafkaListener(id = "dltGroup", topics = "testTopic.DLT")
public void dltListen(String input) {
logger.info("Received from DLT: " + input);
}
}
demo中,監聽testTopic主題的監聽器在處理業務邏輯時如果觸發運行時異常,監聽器會重新嘗試三次調用,當到達最大的重試次數後。消息就會被丟掉重試死信隊列裏面去。死信隊列的Topic的規則是,業務Topic名字+“.DLT”。如上面業務Topic的name爲“testTopic”,那麼對應的死信隊列的Topic就是“testTopic.DLT”