MQ 消息积压在线上怎么排查一次讲清生产过快、消费变慢、重试堆积与止血思路大家好我是一名有 4 年工作经验的 Java 后端开发。消息积压几乎是 MQ 系统里最常见、也最容易被放大的线上问题之一。这篇文章我想系统聊一聊MQ 消息积压到底该怎么排查别一看到积压就只会扩消费者。个人主页文章目录MQ 消息积压在线上怎么排查一次讲清生产过快、消费变慢、重试堆积与止血思路一、前言二、排查消息积压时先看什么三、最常见的积压根因3.1 生产流量突然暴涨3.2 消费逻辑变慢3.3 下游故障导致消费阻塞3.4 重试队列回流四、推荐的排查顺序4.1 先看消费 TPS 和平均耗时4.2 再看消费者线程和机器资源4.3 再看下游依赖4.4 最后再考虑扩容五、线上止血怎么做5.1 核心链路优先5.2 暂时降级非核心消费逻辑5.3 扩容消费者5.4 限流上游六、面试中怎么回答七、总结八、结尾一、前言很多团队看到 MQ 积压第一反应通常是多开几个消费者这个动作有时候有用但很多时候根本治不了根。因为消息积压的原因可能有很多生产速度瞬时暴涨消费者代码变慢下游数据库 / Redis / HTTP 慢重试消息反复回流某个分区 / 队列热点消费幂等逻辑太重所以真正的问题不是“队列里还有多少消息”而是为什么消费速度跟不上生产速度到底是流量问题、消费逻辑问题还是下游依赖问题。二、排查消息积压时先看什么我更建议先看这几件事积压是突然出现还是持续累积是全部 topic 都积压还是个别 topic 积压是所有消费者都慢还是部分实例慢消费耗时是不是最近明显变长下游依赖是否同时变慢这几步能快速决定你后面往哪查。三、最常见的积压根因3.1 生产流量突然暴涨比如活动开始批处理任务触发补偿任务一口气重发这类积压更像短时洪峰。3.2 消费逻辑变慢比如多了个慢 SQL多了个远程调用新加了一个复杂幂等逻辑这类积压通常增长比较持续。3.3 下游故障导致消费阻塞比如Redis 变慢MySQL 锁冲突外部接口超时这类情况经常会让消费线程卡住。3.4 重试队列回流有些积压不是新消息太多而是失败消息一直在重试。这会导致队列看起来越来越长但真正新增业务消息没那么多四、推荐的排查顺序4.1 先看消费 TPS 和平均耗时这一步是最关键的。如果你看到生产 TPS 没明显变化但消费 TPS 掉了那方向基本就是消费端变慢了4.2 再看消费者线程和机器资源重点看线程数CPU内存GC如果这里没问题就更要怀疑下游阻塞4.3 再看下游依赖包括SQL 慢不慢Redis 慢不慢下游 HTTP 有没有超时很多积压问题最后根因其实都不在 MQ 本身。4.4 最后再考虑扩容扩容应该是手段不是第一反应。五、线上止血怎么做5.1 核心链路优先如果积压严重要先区分哪些消息必须优先处理哪些消息可以延后5.2 暂时降级非核心消费逻辑比如暂时关闭非核心回调暂时不做复杂附加处理5.3 扩容消费者如果确认是纯吞吐不够再扩。5.4 限流上游如果生产端洪峰过高而消费端无法承接就要考虑暂时限制某些业务入口六、面试中怎么回答如果面试官问你MQ 消息积压一般怎么排查你可以这样回答第一我不会一看到积压就直接扩消费者而是会先区分积压是短时洪峰还是持续恶化然后看生产 TPS、消费 TPS、平均消费耗时和队列积压增长速度。第二如果生产速度没明显变化而消费速度下降我会优先排查消费者本身是不是变慢了包括消费线程池、JVM、GC、数据库、Redis、下游 HTTP 调用等因为很多积压的根因其实不在 MQ 本身而在消费逻辑或下游依赖。第三如果积压是由失败重试造成的还要把重试消息和正常消息分开看不然很容易误判成单纯的流量太大。第四线上止血时我会先考虑核心消息优先、非核心逻辑降级、必要时扩容消费者或限流上游而不是无脑加实例。七、总结消息积压这个问题真正难的不是“看到积压”而是快速判断是谁生产太快是谁消费太慢是哪一层把链路拖住了如果只记一句结论我觉得可以记住这句处理消息积压最怕头痛医头最稳的方式永远是“先分清生产、消费、下游和重试再决定扩容还是治理根因”。八、结尾如果你觉得这篇文章对你有帮助欢迎点赞、收藏、关注。后面我会继续整理一些更偏实战的 Java 后端和线上排障文章。