6.2 常见问题与故障排除


文档摘要

6.2 常见问题与故障排除 本节摘要:八类高频故障按"现象、根因、定位、处置"四列组织,排查顺序遵循全册追踪单的帧序——消息死在哪一帧,就查哪一段。本节是深夜值班的急救卡:先对号入座,再按帧取证,最后对症处置。 值班夜里接到"消息队列出事了"的告警,最贵的动作是瞎猜。本节把前五章遇到过的所有故障形态收拢成手册,每一条的排查路径都标注了对应章节——急救时先翻表,再动手。 排查总纲:先定帧,再定因 任何消息类故障的第一问都是:消息死在哪一帧? 回顾 2.6 节的全流程:编码、通道发出、Broker 接收、交换机判决、入队、投递、签收。用管理界面看三个数——发布速率、队列堆积、消费速率——三个数的组合能直接把故障分到段。

6.2 常见问题与故障排除

本节摘要:八类高频故障按"现象、根因、定位、处置"四列组织,排查顺序遵循全册追踪单的帧序——消息死在哪一帧,就查哪一段。本节是深夜值班的急救卡:先对号入座,再按帧取证,最后对症处置。

值班夜里接到"消息队列出事了"的告警,最贵的动作是瞎猜。本节把前五章遇到过的所有故障形态收拢成手册,每一条的排查路径都标注了对应章节——急救时先翻表,再动手。

排查总纲:先定帧,再定因

任何消息类故障的第一问都是:消息死在哪一帧? 回顾 2.6 节的全流程:编码、通道发出、Broker 接收、交换机判决、入队、投递、签收。用管理界面看三个数——发布速率、队列堆积、消费速率——三个数的组合能直接把故障分到段。分诊逻辑画成流程图,值班时按图走即可:

图 18 故障分诊流程:三个数字定区段

图 18 故障分诊流程:三个数字定区段

用管理界面看三个数时有个细节提醒:速率要看时间窗而不是瞬时值,界面里的消息速率图默认五秒刷新,抖动很大——把时间窗拉到五分钟以上再下判断,否则容易把正常毛刺读成故障。

八类高频故障速查表

类别 典型现象 根因 处置(详见章节)
堆积型 ready 持续增长 消费能力不足或消费端卡死 5.4 三段定位,紧急先扩消费者
蒸发型 队列与业务都不见消息 自动确认或未持久化 3.1、3.2,修复签收与三件套
拒连型 客户端连接被拒 认证失败或 vhost 错误 4.2 核对账户与 vhost
参数冲突型 启动即通道报 406 声明参数漂移 2.4 迁移流程对齐参数
重复消费型 业务出现重复处理 重投递叠加无幂等 3.4 变式与 5.5 幂等表
顺序错乱型 状态机报错 多消费者或重投乱序 3.4 分片保序改造
资源阻塞型 发布时快时慢 内存或磁盘水位触发 4.1 参数与 4.4 告警处置
连接泄漏型 连接数缓涨直至拒绝服务 每任务建连不复用 2.5 单例化改造

三个最疼的故障,展开拆

故障一,堆积型。现象:ready 每分钟涨十万。定位三步:先看 consumers 列——为零就是消费者全体掉线,回 Connections 页查掉线原因(多半伴随 OOM 或网络割接);不为零再看消费速率与发布速率的剪刀差,速率接近说明只差容量,速率远低说明处理卡住;处理卡住的深挖用 5.4 节热区表——八成是回调里的慢操作。紧急处置按优先级:扩消费者实例(最快)、临时提高 prefetch(处理快时有效)、启用降级把非关键下游断开(6.1 案例一的预案)。禁止动作:删队列——那等于把事故升级成数据事故。

故障二,蒸发型。现象:业务说没收到,队列里也查无此消息。这是全册追踪单风险点的合流现场,按嫌疑度排查:第一嫌疑 auto_ack(3.1 节,消费者崩溃即蒸发),第二嫌疑缺 delivery_mode=2(3.2 节,重启即蒸发),第三嫌疑路由静默丢弃(2.6 节,发出去就没进过队列),第四嫌疑 TTL 过期无死信(3.3 节,活太老被清)。每个嫌疑一条取证命令:

# 嫌疑一取证:未签收数是否异常归零(掉线即蒸发窗口) rabbitmqctl list_queues name messages_ready messages_unacknowledged # 嫌疑二取证:persistent 列与消息数是否一致 rabbitmqctl list_queues name messages persistent # 嫌疑三取证:绑定关系是否真的存在 rabbitmqctl list_bindings source_name destination_name routing_key | grep trace # 嫌疑四取证:队列是否声明了 TTL 而未配死信 rabbitmqctl list_queues name arguments

结果与解读:四条命令跑完,四类丢失原因基本现形。预防措施就是把 3.5 节的检查点地图前置到上线评审——急救手册治标,检查点治本。

故障三,重复消费型。现象:下游账务出现重复记录。根因必然是组合:消息队列的至少一次语义(重投递无法避免)叠加消费端无幂等。处置分两层:消费端加幂等表(消息 ID 或业务键唯一索引,重复插入直接签收跳过),业务流程加自然幂等设计(按主键更新而非插入)。认知纠偏:重复不是要"消灭"的故障,而是要"容忍"的特性——追求不重不丢的代价是分布式事务,绝大多数业务付不起,幂等才是标准答案(3.4 节判级与 5.5 节实现呼应)。

完整演练:一次综合故障的全流程处置

背景:演练环境注入复合故障——某服务发布代码更新后,队列开始堆积且偶发 406 报错。假装我们不知道原因,走一遍标准处置。

操作:第一步,三数分诊——发布速率正常、堆积增长、消费速率偏低,故障定在消费侧叠加配置异常。第二步,翻日志发现 406 PRECONDITION_FAILED:

rabbitmqctl list_queues name arguments # 预期输出: # trace.orders [] # trace.orders.retry [{"x-message-ttl", 60000}]

结果与解读:新版本代码把重试队列的 TTL 从六万改成三万毫秒,旧队列参数不可变——406 导致通道反复重连,消费吞吐随之下降。两个故障一个根因,正是 2.4 节"声明收敛"纪律要防的事故形态。处置:回滚该服务的队列声明到共享基础设施代码,重新部署,堆积在一小时内消化。复盘沉淀:把"队列声明必须走共享模块"写进代码评审 checklist——这是 6.1 节总表第 5 条的来历。

变式:演练只留 406 不留慢消费,观察故障表现如何"伪装"成纯堆积——单一根因在不同环境下表现多样,这正是"先定帧再定因"总纲的价值:帧序不受表象干扰。

值班交接的三个习惯

手册之外,三个流程习惯决定深夜的混乱程度。习惯一,告警带上下文:告警消息里附上队列名、三数快照与最近变更,值班者不用从零猜。习惯二,处置动作留痕:每个操作记时间与结果,故障复盘与交接都靠它。习惯三,疑难故障升级有门槛:自己排查超过三十分钟无头绪就拉人——消息系统的故障窗口每多一分钟,堆积就多一分,单打独斗不是美德。

💡 关键直觉:故障排查的效率取决于"假设空间收窄的速度"。三数分诊一上来就砍掉三分之二的假设,帧序又砍一半——先分诊再深挖,永远比逐条试错快。

本节要点回顾

  • 总纲:先定帧再定因,三数分诊是所有排查的入口;
  • 八类速查:堆积、蒸发、拒连、参数冲突、重复、乱序、资源阻塞、泄漏;
  • 蒸发四嫌:自动确认、缺持久化、静默丢弃、TTL 无死信,各有取证命令;
  • 重复消费:至少一次语义的伴生品,幂等是标准答案不是补丁;
  • 三个习惯:告警带上下文、处置留痕、升级有门槛。

手册收尾。最后一节抬起头看路:版本怎么选、升级怎么做、消息队列的大方向在哪里。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U