重试队列、死信队列与补偿机制
消费失败不是异常边角,而是消息系统的常态。重试、死信、告警和补偿决定了失败消息能不能被闭环处理。
重试队列、死信队列与补偿机制
消费者失败很正常。网络超时、数据库锁冲突、下游接口不可用、数据格式错误,都可能让一条消息处理失败。
关键问题不是失败会不会发生,而是失败后系统能不能有序处理。
Rendering diagram...
不要无限重试
无限重试会带来两个问题:
第一,坏消息一直阻塞正常消息。
第二,系统不断消耗资源处理注定失败的消息。
更合理的方式是有限次数重试,失败后进入死信队列。
重试策略
常见策略包括:
- 立即重试。
- 固定间隔重试。
- 指数退避。
- 延迟队列重试。
短暂网络抖动适合立即重试。下游服务故障适合延迟重试。数据本身错误则应该尽快进入死信。
死信队列
死信队列用于存放无法正常消费的消息。
死信消息应该保留原始 payload、失败原因、失败次数、最后失败时间和消费者信息。
{
"message_id": "evt_10001",
"topic": "order-events",
"reason": "invalid order status",
"retry_count": 5,
"payload": {
"order_id": 10001
}
}
补偿机制
死信队列不能只是垃圾桶。它必须进入处理闭环。
处理方式包括:
- 告警。
- 人工修复数据。
- 重新投递。
- 执行补偿任务。
- 标记忽略并记录原因。
小结
重试解决暂时失败,死信承接长期失败,补偿负责最终收敛。没有死信和补偿的消息系统,只是把错误藏起来了。