CodeWalk

Kafka消息重试与死信队列(Dead Letter Queue)设计

作者:编译有声 · 2026-05-30 12:55

在实际生产环境中,Kafka消费者处理消息可能失败。请设计一个完整的消息重试架构,包括重试Topic的设计(可延迟重试)、重试次数限制、以及死信队列(DLQ)的存储和告警策略。请用Java伪代码说明Kafka消费端重试的实现。

回答

编译有声

重试与死信架构设计

  1. Topic设计

    • orders-topic:主消费Topic
    • orders-retry-1:第1次重试(延迟5s)
    • orders-retry-2:第2次重试(延迟30s)
    • orders-retry-3:第3次重试(延迟10min)
    • orders-dlq:死信队列(最终失败)
  2. 架构流程

    主Topic → 消费失败 → headers中retryCount=1 → retry-1
    retry-1 → 消费失败 → headers中retryCount=2 → retry-2 
    retry-2 → 消费失败 → headers中retryCount=3 → retry-3
    retry-3 → 消费失败 → DLQ
    
  3. 延迟实现

    • 方式1:Kafka本身不支持延迟,使用定时任务(如延时队列发送到retry Topic)
    • 方式2:基于时间戳过滤,消费者只处理时间戳≤当前时间的消息
    • 方式3:集成Redis/ZK实现延迟消息
  4. 死信队列DLQ

    • 单独Topic:app-dlq
    • 记录原始消息体 + 失败原因 + 重试次数 + 时间戳
    • 告警:钉钉/Slack通知SRE,失败次数超过阈值触发
  5. Java伪代码

void processMessage(ConsumerRecord<String, String> record) {
    try {
        // 业务处理
        process(record.value());
        consumer.commitSync();
    } catch (Exception e) {
        int retryCount = getRetryCount(record.headers());
        if (retryCount < MAX_RETRIES) {
            // 发送到延迟重试Topic
            sendToRetryTopic(record, retryCount + 1);
        } else {
            // 发送到DLQ
            sendToDLQ(record, e.getMessage());
        }
    }
}