运维巡检发现 order.dlq 有 8234 条消息,最早的躺了 19 天,x-death 里 reason 全是 expired,TTL 设的是 30 分钟。第一次遇到会往复杂处想,其实漏掉的多是个小前提。

rabbitmqctl list_queues name messages consumers | findstr dlq
rabbitmqadmin get queue=order.dlq count=10 ackmode=ack_requeue_false

主队列配了 x-message-ttl,但没有消费者处理超时消息,过期后自动转到死信队列。死信队列只声明了没人消费,也没配告警。这一点先确认清楚,后面就不用反复试。

「死信队列无人处理」相关的日志我一般连着看前后五分钟,单看一条报错经常判断不出是哪一步失败。临时改动用注释写上日期和原因,过两周自己都记不清为什么这么写。

动手前把原文件复制一份带时间戳,出问题立刻换回去,比现场分析快得多。

具体做法是,先抽样 10 条死信 确认是消费不过来还是业务本身失败;给死信队列配消费者 按 reason 分类处理;超过 24 小时未处理的死信转成工单;把死信队列长度加进监控 超过 100 条告警。

改完照着核一遍,死信队列长度降到 100 以内 面板上能看到每条的 reason 分布 新死信能触发告警。

作者 9823189