这是《RocketMQ 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 故障排查的第一步是固定时间线和影响面,再分层验证。不要先改配置,也不要先重启。RocketMQ 的问题通常由路由、权限、订阅、位点、存储、下游依赖或客户端版本共同造成,盲目变更会破坏证据。
23.1 排查框架
confirm impact
-> collect timeline
-> classify symptom
-> check client
-> check route
-> check broker
-> check storage and os
-> check downstream
-> apply mitigation
-> root cause review
必须记录:
- 开始时间和恢复时间;
- 环境、集群、Topic、消费组;
- 错误率和延迟曲线;
- 发布、扩缩容、配置变更;
- 依赖服务状态;
- 最终止损动作。
23.2 发送失败
常见错误:
| 错误 | 方向 |
|---|---|
| No route info of this topic | Topic 未创建、路由错误、权限 |
| send timeout | 网络、Broker 繁忙、磁盘慢、大批量 |
| topic not exist | 环境错误或自动创建关闭 |
| no permission | ACL 配置 |
| message too large | 超过限制 |
| broker busy | 繁忙、锁竞争、磁盘或请求堆积 |
检查顺序:
client config
-> nameserver address
-> topic route
-> acl
-> broker metrics
-> producer thread / batch size
保留发送失败日志中的业务键,便于后续对账。
23.3 消息丢失
先定义丢失:
business DB committed
-> event not sent
-> broker not persisted
-> consumer not pulled
-> business not applied
排查:
- 查业务库和本地事件表;
- 查生产日志和 SendStatus;
- 按消息 ID 或 Key 查 Broker;
- 查消费轨迹;
- 查消费者业务处理表;
- 查死信和重试;
- 执行业务对账。
如果 Broker 没有消息,优先查生产端;如果 Broker 有但消费没有,优先查路由、订阅和位点;如果已消费但业务未生效,优先查消费事务和幂等。
23.4 消费积压
分类:
| 现象 | 原因 |
|---|---|
| 消费组不在线 | 发布失败、崩溃、配置错误 |
| 队列无人消费 | 实例少、重平衡异常、订阅不一致 |
| 消费耗时高 | 慢 SQL、下游慢、线程不足 |
| 单队列热点 | 顺序 key 热点 |
| 重试风暴 | 下游故障 |
| 位点落后 | 手工重置或长期故障 |
止损顺序:
protect downstream
-> disable noncritical logic
-> scale consumers
-> improve batch size if safe
-> isolate hot topic
-> add queues if architecture allows
先保护下游数据库,再追求追平速度。
23.5 顺序异常
证据链:
message key
-> queue id
-> queue offset
-> store time
-> consume time
-> consumer instance
常见原因:
- 队列选择器不稳定;
- 发送重试换队列;
- 使用并发消费;
- 消费重试跳过;
- 重放乱序;
- 业务时间与存储时间混淆。
处理前先确认业务是否真的依赖顺序,以及乱序窗口影响哪些状态。
23.6 Broker 磁盘问题
检查:
df -h
du -sh store/*
iostat -x 1
dmesg | grep -i error
broker.log
clean commitlog log
判断:
| 现象 | 可能 |
|---|---|
| commitlog 增长快 | 写入高、保留长、消费落后 |
| consumequeue 异常大 | 队列或 Topic 过多 |
| index 过大 | Key 过多或轨迹全量 |
| 磁盘 util 高 | 真实 IO 瓶颈 |
| 文件句柄不足 | 队列多、进程限制低 |
磁盘接近拒写时优先扩容,确认位点前不要手工删除数据文件。
23.7 重平衡异常
现象:
- 消费暂停;
- 重复消费增加;
- 部分队列无人处理;
- 消费者实例列表变化频繁。
检查:
- 消费者健康检查;
- 发布滚动策略;
- 网络闪断;
- GC 或 CPU 饥饿;
- 订阅关系一致性;
- 消费者版本;
- 会话超时配置。
频繁上下线比一次重平衡更值得治理。
23.8 事务消息问题
常见现象:
| 现象 | 可能 |
|---|---|
| 半消息悬挂 | 本地事务未知、回查失败 |
| 本地成功但消息未投递 | 回查返回错误 |
| 本地失败但消息投递 | executeLocalTransaction 返回 COMMIT |
| 重复事件 | 回查和补偿并发 |
检查:
- half message ID;
- transactionId;
- 本地事件表状态;
- 回查日志;
- 回查异常和超时;
- 生产者监听器配置。
23.9 常用命令
示例命令名称随版本可能不同:
mqadmin clusterList -n rocketmq-namesrv:9876
mqadmin topicStatus -n rocketmq-namesrv:9876 -t OrderTopic
mqadmin consumerProgress -n rocketmq-namesrv:9876 -g order-consumer
mqadmin topicRoute -n rocketmq-namesrv:9876 -t OrderTopic
高危命令:
- 删除 Topic;
- 重置位点;
- 关闭 Broker;
- 修改权限;
- 清理存储文件。
必须先备份信息并获得变更确认。
23.10 应急预案
每类故障都应有 Runbook:
| 故障 | 止损 |
|---|---|
| Broker 不可用 | 切换副本、客户端熔断、业务降级 |
| 磁盘将满 | 停批处理、扩容、清理确认过期数据 |
| 消费积压 | 保护下游、扩消费者、旁路非关键逻辑 |
| 重试风暴 | 熔断下游、限流、暂停非核心 |
| 消息丢失疑云 | 先对账,不盲目重放 |
| 死信爆发 | 冻结重放、修复逻辑、小批量验证 |
本章小结
故障排查要沿着“业务事实、消息轨迹、路由状态、存储指标、下游依赖”的链条推进。先确认影响和证据,再做可回滚止损;恢复后必须做对账和根因复盘。大多数疑难问题不是单点故障,而是状态、配置和补偿逻辑共同作用的结果。
思考题
- 为什么故障初期不建议立即重启 Broker?
- “消息丢失”有哪几个不同层面?
- 消费积压时为什么先保护下游?
- 判断顺序异常需要哪些证据?
- 哪些 mqadmin 命令属于高危操作?