MQ消费重试的常见手段
在使用MQ时,必不可少的需要结合当前场景,考虑消费失败时如何处理。对于消息不重要的场景,失败就失败了,继续往下消费就行。但对于消息重要的场景,就需要有一定的机制去保证消息最终处理成功。
机制的手段有很多,大体思路都是,先进行重试,重试一定次数之后就走兜底逻辑。
- 对于重试,可进行固定时间间隔的重试或做间隔时间递增的重试等
- 对于兜底逻辑,包括消息投递到死信队列、告警、人工补偿、定时对账补偿等
下面主要讲如何使用好kafka和pulsar自带的消费重试功能,对于兜底逻辑来说只做异常日志的记录,其它手段较灵活,不在本文讨论范围内。另外本文使用的spring-kafka版本为2.3.0,pulsar版本为2.7.0。
kafka重试
消费失败重试
这里使用的是spring-kafka客户端
一个spring-kakfa consumer的使用例子如下:
@Component
@Slf4j
public class DemoListener {
@KafkaListener(id = "groupId", topics = "demo-topic",
containerFactory = "defaultKafkaListenerContainerFactory")
public void handleMsg(ConsumerRecord<?, String> record, Acknowledgment ack) {
try {
doHandleMsg(record);
//流程正常结束的手动ack。若中间有流程抛异常,会进入kafka的重试流程进行自动重试
ack.acknowledge();
} catch (Exception e) {
log.error("[DemoListener.handleMsg] error, record:{}, exception:{}", record, Throwables.getStackTraceAsString(e));
}
}
}
对于consumer的配置,定义在了bean defaultKafkaListenerContainerFactory
@Bean("defaultKafkaListenerContainerFactory")
public KafkaListenerContainerFactory<ConcurrentMessageListenerContainer<String, String>> kafkaListenerContainerFactory() {
ConcurrentKafkaListenerContainerFactor