面试知识库
基础

死信队列#

一句话答案#

消费失败重试超上限后进入死信队列(DLQ),人工介入处理:修复后重新投递或补偿处理。

核心要点

消费失败的处理策略:

1. 重试机制

第一次失败 → 等待 5s 重试
第二次失败 → 等待 30s 重试
第三次失败 → 等待 1min 重试
...
达到最大重试次数 → 投递到死信队列

(指数退避策略,避免频繁重试打爆下游)
plaintext

2. 死信队列(Dead Letter Queue,DLQ)

死信队列是专门存放”处理失败”消息的队列,消息进入死信队列的条件:

① 消息消费失败且超过最大重试次数
② 消息在队列中等待超过 TTL(消息过期)
③ 队列长度超过上限(消息被挤出)
plaintext

RocketMQ 的死信队列:

// 消费失败达到最大重试次数(默认16次)后,自动投入死信队列
// 死信 Topic 名称:%DLQ%消费者GroupID

// 监控和处理死信:
consumer.subscribe("%DLQ%MyConsumerGroup", "*");
consumer.registerMessageListener((MessageListenerConcurrently) (msgs, context) -> {
    // 告警、人工处理、记录到 DB 等
    alertService.sendAlert(msgs.get(0));
    return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
});
java

Kafka 的死信队列(需自己实现):

处理死信的策略:

  1. 人工介入:告警 → 运营人员在控制台查看死信 → 手动重新处理
  2. 自动重试:定时任务将死信重新投递(配合幂等性)
  3. 降级处理:记录到数据库,由补偿任务处理
面试回答(2分钟版)

死信队列是专门存放消费失败消息的队列,相当于消息系统的”退件仓库”。消息进入死信队列有三种条件:消费重试超过最大次数、消息在队列中超过TTL过期、队列长度超过上限被挤出。以RocketMQ为例,消费失败后会按指数退避策略自动重试,从5秒逐步递增到2小时,默认重试16次后消息自动投入死信Topic,Topic名称格式是%DLQ%加ConsumerGroupID。Kafka没有原生死信队列,需要自己实现:消费失败后根据重试次数决定投递到重试Topic还是死信Topic。处理死信的策略一般有三种:人工介入通过监控告警让运维人员在控制台查看并手动处理;自动重试由定时任务将死信重新投递配合幂等性保证;降级处理记录到数据库由补偿任务异步处理。实际生产中必须对死信队列做监控告警,因为死信积压往往意味着下游系统出了严重问题,比如数据格式变更、依赖服务不可用等,需要及时排查根因而不能仅仅依赖重试。

追问与易错

追问方向:

  • “死信队列和重试队列的区别?”→ 重试队列用于消费失败后延迟重试(通常有最大重试次数),死信队列是重试耗尽后的最终归宿,存放无法正常消费的消息等待人工介入
  • “死信消息怎么处理?”→ 通常设置告警通知开发人员,人工排查失败原因后修复逻辑并重新投递;也可以写专门的死信消费者做补偿处理或记录到数据库供后续分析
  • “Kafka 原生支持死信队列吗?”→ Kafka 原生不支持,需要自行实现:消费失败超过重试次数后将消息发送到一个专门的 DLQ Topic;RocketMQ 和 RabbitMQ 原生支持死信队列机制

易错点:

  • ❌ 只知道概念不知道原理——面试官会追问底层实现
  • ❌ 缺乏实际使用经验——结合项目场景回答更有说服力