消息中间件出现消息堆积时如何排查处理?

考查重点:生产、消费速率与积压来源。比较生产速率与成功消费速率,查热点分区、慢处理和下游;限流保护后修瓶颈,再扩消费者追积压并核幂等

本题目录

参考答案

核心回答

消息堆积先确认哪些消息在等、等待多久、积压是否持续增长,再比较生产速率与业务处理成功速率,沿着生产端、Broker、消费者和下游依赖定位瓶颈。处理上先保护系统,再修复瓶颈并追赶积压,最后核对业务结果,不能一看到队列变长就增加消费者。

首先看积压范围:是整个集群、某个 Topic、某个消费组,还是单个分区或队列。同时观察积压趋势、最老消息等待时间、生产速率、消费成功速率和错误率。削峰期间短暂积压且能在业务时限内消化,可能符合设计;积压量不断增长,或者老消息迟迟不前进,才需要进一步处理。

指标还要结合消息系统的语义理解。例如 Kafka 基于已提交位点统计的 lag,可能受到提交周期影响,不直接等于业务未处理条数;已拉取位置、已提交位置和业务完成状态是不同概念。RabbitMQ 则要区分尚未投递的消息与已投递但尚未确认的消息,后者可能已经堆在消费者内部。

沿链路定位瓶颈

  • 生产端:是否流量突增、重复发送、重试放大,或者某个业务 key 导致数据倾斜。生产速率没变而消费速率突然下降,优先找消费链路变化。
  • 消费者:实例是否在线、订阅和分配是否正常,是否刚发布、频繁重启或再均衡;处理线程是否在慢 SQL、外部接口、锁、线程池或连接池上等待。结合分阶段耗时、错误日志和线程状态判断,不能只看 CPU。
  • 下游依赖:数据库是否锁等待、连接耗尽或写入饱和,外部服务是否超时、限流。消费者多数时间在等一个已经饱和的数据库时,盲目增加并发可能让数据库更慢。
  • Broker 与网络:是否有磁盘、IO、网络或配额瓶颈,客户端是否拉取失败。历史积压从磁盘冷读,也可能增加 Broker 压力。不能因为报了超时,就直接认定需要扩容 Broker。

还要单独查持续失败的“毒消息”:同一条消息反复重试,可能拖住有序队列,或者造成重投循环。应保留失败原因,通过有上限的重试、退避和失败队列等方式处理;有顺序要求时,还要明确隔离后是否允许后续事件继续执行。

怎样处理和追赶积压

先止住继续恶化。 流量超过能力时,对可延迟业务限流、降级或暂缓生产,保留必要的业务入口;依赖故障时先恢复依赖并限制重试,避免恢复瞬间再次打满。同步评估磁盘剩余空间、消息保留期或 TTL,以及业务最晚处理时间,防止还没追上就发生过期或数据被清理。

再提高真正有效的消费能力。 修复慢 SQL、重复查询和阻塞点;业务支持时批量处理,减少逐条网络和数据库交互。增加消费者、线程或预取量,都要确认下游还有余量,并观察成功吞吐、延迟和内存是否改善。预取变大只是把更多消息交到客户端,不等于它们已经处理完成。

扩容还受分配模型约束。以 Kafka 4.1 的常规 KafkaConsumer 消费组为例,同组一个分区分配给一个消费者,分区已经用满后再加实例不会直接增加分区消费并行度。其他 MQ 和 SDK 可能采用不同粒度的负载均衡,不能把这个上限套到所有产品。

最后有控制地消化历史积压。 保留新流量与补偿任务的容量预算,避免追赶任务挤垮实时业务。拆分队列、迁移消息或并行处理前,要确定业务 key 的路由和顺序要求;不能为了均匀分流,把同一业务实体的有序事件随意打散。

如果积压量为 B、稳定的新增速率为 P、有效消费速率为 C,只有 C 大于 P 时,才可以粗略估计追赶时间为 B / (C - P)。这里假设速率相对稳定,实际还要考虑重试、热点和下游波动。

怎样确认恢复

不只看队列深度下降,还要看最老消息等待时间、业务完成状态、失败及重试数量、下游负载和消费进度是否持续正常。消息从 Broker 搬进本地无界线程池,或者提前确认、跳过位点,都可能让监控变好看,却没有完成业务处理。

例如订单事件因数据库锁等待而积压,应先解决锁竞争,再在数据库能承受的范围内恢复消费。订单写入成功后推进消费进度,同时保留幂等约束,处理重投;这比直接扩大消费者数量更能对应实际瓶颈。

常见追问

能直接清空队列或跳到最新位点吗?

要看消息的业务含义和恢复来源。支付、订单等关键事件通常不能直接跳过;可以过期作废的状态通知,也要按业务规则处理。需要重放时,应确认源数据完整、补偿范围明确,并控制补偿速率和幂等,不能把“以后再补”当成已经恢复。

扩分区后就能保持原来的顺序吗?

不能直接这样推断。Kafka 提供的是分区内的记录顺序;增加分区可能改变后续消息的 key 路由,应用内部并行处理也可能打乱业务完成顺序。需要按业务实体设计路由、迁移和消费方式,跨分区不会自动获得全局顺序。

参考资料

  • 国内:JavaGuide:RocketMQ 常见问题总结:借鉴“如何解决消息堆积问题”中的范围、速率、耗时与分配关系,组织正文的排查顺序,并说明扩容须对应真实瓶颈。
  • 国内:advanced-java:消息队列延时、过期与积压:采用下游数据库阻塞、并行度增加存在上限、批量处理和优化单条消费流程的分析,解释吞吐、保留期与补偿的关系。
  • 国内:阿里云 Kafka:使用时出现消息堆积:参考位点、提交频率、消费耗时与实例监控的说明,解释正文中 lag 波动、处理阻塞及服务端资源问题的区分。
  • 国外:Apache Kafka 4.1:KafkaConsumer:位点、消费组和消费进展章节说明拉取位置与提交位置的差别,以及分区分配、慢处理和再均衡的约束。
  • 国外:RabbitMQ:Consumers:确认模式、预取和 Consumer Capacity 章节解释已投递未确认消息、消费者过载,以及为何容量指标只能作为扩容线索。

相关面经

14 篇

启云方

AI 应用开发工程师
一面
查看原面经 →
Kafka 消息堆积怎么排查和解决?

水滴公司

AI 全栈工程师
校招秋招一面、二面
查看原面经 →
你对哪个 MQ 比较熟?那比如 MQ 它消费端出现了积压,你觉得这个问题怎么排查?

阿里巴巴

Agent 开发工程师
一面
查看原面经 →
如何保证大流量下消息处理的鲁棒性?

拼多多、荣耀、立元科技、得物、华橙

面经合集
查看原面经 →
项目中消息队列积压了怎么办

拼多多

服务端开发
秋招一面
查看原面经 →
有topic发生消息积压怎么办
展开剩余 9 篇面经

字节跳动

Agent 开发
校招秋招一面
查看原面经 →
● MQ 的消息积压如何处理?

百度

后端开发
秋招一面
查看原面经 →
MQ 突然积压几十条消息,怎么分析原因?

招银科技

后端开发工程师(AI / Agent 方向)
社招
查看原面经 →
消息中间件消息堆积怎么排查

网易

AI 应用开发工程师
查看原面经 →
RabbitMQ消息丢失、重复消费、堆积、阻塞的成因和线上解决方案。

阿里巴巴

后端开发
日常实习一面
查看原面经 →
如果消费者处理速度跟不上生产者的速度,怎么解决

高德

Agent 后端开发
日常实习一面
查看原面经 →
g. Kafka消息堆积怎么处理?

美团

全栈开发工程师
一面
查看原面经 →
消息队列的消息积压怎么办?

京东

AI 后端 / Agent 开发
日常实习一面
查看原面经 →
b. 消息积压问题如何处理

字节跳动

后端开发工程师(AI / Agent 方向)
四面
查看原面经 →
kafka消息堆积怎么处理

收录题集

1 个来源,共1 份题集

相关题目

4 题