← 中文资源

简体中文版本

死信队列

死信队列把重试耗尽或不可重试的消息移到一旁,保留上下文供排查,同时让消费者继续处理后续消息。

阅读英文原文

一条坏消息不应阻塞整个流

消费者按顺序处理消息。一条格式错误的消息失败、重试、再次失败,并阻塞后面所有消息。死信队列在达到重试上限或遇到不可重试错误后把消息移走。消费者继续运行,运维人员可以带着错误上下文检查被停放的消息。

{
  "RedrivePolicy": {
    "deadLetterTargetArn": "arn:aws:sqs:region:account:orders-dlq",
    "maxReceiveCount": 5
  }
}

示例是 SQS 的重驱动策略。RabbitMQ 使用死信交换机;Kafka 常用独立的 DLQ topic,并附带原 topic、partition、offset 和错误头。机制不同,策略相同:有界重试、保留上下文、保持可见。

区分失败类型

不是所有失败都该进死信队列。超时或暂时不可用的依赖应使用指数退避加抖动重试。模式不匹配、非法负载或授权失败,在生产方或数据修复前都是永久错误,重试只会浪费容量。有些系统把重试队列和死信队列分开:瞬时失败获得延迟,永久失败立即停放。

要保留原始消息、异常、消费者版本和尝试次数。没有这些上下文,死信队列只是一堆难以理解的负载。对队列深度和消息年龄告警;即使主链路健康,持续增长的死信队列也是运维信号。

谨慎重放

重放是一次新的生产事件。消费者必须幂等,因为原投递可能已部分成功。乱序重放死信队列可能丢失顺序,需确认消费者是否依赖序列。模式或代码变化后,先重放到预发消费者。记录谁在何时重放了什么。

何时使用

当有界重试后消息仍可能无法处理,而阻塞进度不可接受时,使用死信队列。优点是隔离与诊断;代价是多一个需要监控、保护和清理的队列。与无限重试相比,死信队列让失败可见;与直接丢弃相比,它保留了恢复机会。