LIANERShenYu 生产故障复盘 · 2026-11-02PDF
LIANER FITMOMENTS · ENGINEERING REVIEW
评审报告

故障复盘

11-02 下午生产接口全部中断 43 分钟:发生了什么、为什么、以后怎么防。

适用William · 后端研发 · 运维值班
来源2026-11-02 15:49–16:32 生产网关故障
版本v1.0 · 2026-11-02
练二一下,好状态。
练二健身 · 研发中心 hellolianer.com
01
Scope

结论

15:49 到 16:32,小程序和后台的业务接口全部打不开,约 43 分钟没有一笔新订单。

直接原因是 ShenYu 网关内存里的路由表丢了:后台数据库里的路由一直完好,但网关不认了,所有请求被拒。故障开始前 1 分钟内,有人用共用的管理员账号在网关后台手工改了路由(新建又删除了 /payment、/settlement 分组),删除 /payment 后 2 秒订单就断了,所以这些手工改动最可能是起点,但它为什么会波及全部四个服务,还要看网关日志才能定论。我们先推送配置没救回来,最后重启网关恢复;重启时网关被起了两次,中间多出几分钟 502。

01前端小程序 · 新后台地址都是 /prod-api/…02入口nginx16:27 起两个网关时这里报 50203网关ShenYu 网关(内存里的路由表)15:49 起路由丢失,-107 / -10204服务user · coach · ground · payment服务本身一直正常
请求链路:红框是这次坏掉的网关路由表,服务本身一直正常
更正首版复盘

首版写的「今天没人改过网关配置」不对。当时只看了现存路由的修改时间,被删掉的分组不会留下修改时间;网关后台的「操作记录」显示今天 15:43–16:10 有 12 次手工改动。

02
Overview

断在哪里

网关查一张内存路由表决定请求交给哪个服务;路由由后台经 ZooKeeper 推过来。

网关后台人在网页上改路由;存数据库ZooKeeper把改动推给网关(兼服务注册中心)ShenYu 网关收到推送后更新内存路由表今天断在哪15:43–15:54 后台被手工改动,15:49 起网关丢路由16:25 再推送也没生效,只有重启网关才恢复
路由的改动从后台经 ZooKeeper 推给网关;这次推送链路也失灵了
03
Timeline

时间线

北京时间;后台操作记录的时间原样是 UTC,已加 8 小时换算。

14:45结算相关代码合入主分支(lianer-back !299、admin-next !26)
14:47–15:48结算服务生产发布 3 次(14:47、15:16、15:44),新后台发布 1 次,均成功
15:43:28网关后台:新建规则 /payment/back/getCards,10 秒后删除
15:45:54网关后台:修改 /settlement 分组的转发目标
15:48:03网关后台:新建 /settlement 分组,18 秒后删除
15:48:33网关后台:新建 /payment 分组
15:48:50网关后台:删除 /payment 分组
15:48:52最后一笔订单;之后 43 分钟零订单
15:53–15:54网关后台:/settlement 分组改名为 /settlement1 又改回
16:00–16:06payment 服务生产发布(另一位同事),没有恢复
16:09–16:10网关后台:删除 /settlement 分组、20 条规则、20 条接口登记
16:16William 报告线上全崩,开始排查
16:19只读探测:/user 报 -107,/payment 报 -102;后台路由数据完整
约 16:25经 William 同意,后台推送全部配置,接口全报成功,网关没变化
16:27 / 16:28生产机上先后起了两个网关进程,入口变成 502
约 16:30停掉两个进程,只起一个
16:32:39第一笔新订单,业务恢复
17:02复测 user、payment 正常
18:41复测四个服务均正常;/settlement 仍不通(分组已被删)
04
Causes

原因

把能证实的、高度吻合但没证实的、完全不知道的分开写。

1推测的依据

原因分三档确定:网关内存路由丢了后台数据完整,网关却报找不到路由已证实确定:后台推送救不回来16:25 推送全报成功,网关不变已证实确定:重启时起了两个网关16:27、16:28 各一个,期间 502已证实推测:后台手工改路由触发15:48:50 删 /payment,2 秒后停单高度吻合未知:为何波及全部服务需网关和 ZooKeeper 日志待查最可能的起点是 15:43–15:48 的后台手工改动
「推测」一档等网关日志确认;「未知」一档决定要不要改网关本身

2贡献因素

05
Impact

影响

业务接口全断 43 分钟;人脸开门不走网关,一直正常。

时长15:49 到 16:32,约 43 分钟
范围小程序(会员、教练、店长)和新后台的全部业务接口
订单中断期间 0 笔;前一小时约每 10 分钟 7–22 笔。恢复后 16:30–17:00 共 57 笔,有补单
未受影响门店人脸开门(期间每 10 分钟仍有 2–5 次成功开门)、数据库、各服务进程
遗留结算管理相关接口目前仍不通,因为 /settlement 分组在 16:10 被删除
0102015:49–16:320 笔15:0015:3016:0016:3017:00每 10 分钟成交订单数(私教 + 会员卡 + 体测,含美团、抖音核销)
订单数据来自生产库只读查询;15:40 一档的 11 笔都在 15:48:52 之前
06
Response

我们做了什么

先只读定位,再推送配置,最后重启;中间有两处弯路。

16:19只读查后台:插件、分组、规则都在,判断是网关内存和后台不同步
约 16:25经同意推送 10 个插件配置、接口登记和全量数据:全报成功但无效
16:27给出重启命令;第一版用了旧手册路径,与生产实际不符,按现场修正
16:29发现两个网关进程,指导停掉两个只起一个
16:32恢复;17:02、18:41 两次复测
做对的

先只读、不乱改;动生产前征得同意;恢复后用真实接口逐个复测。

弯路

一是只看了现存路由的修改时间,漏掉了后台「操作记录」,误判为没人改过;二是重启手册路径过时、没有进程数检查,导致网关被起了两次。

07
Lessons

教训

四条规矩,写进值班手册。

01

生产路由不在高峰手工改

网关后台的一次删除就可能让全站停摆。改之前在群里说,改完马上用真实接口验证,发现异常立刻回退。

02

排查先看操作记录

网关后台首页的「操作记录」能直接看到谁、几点、改了什么(时间要加 8 小时)。这次漏看,多绕了半小时判断。

03

「同步成功」不等于生效

后台只保证写出去了,网关收没收到要用真实接口验证。

04

网关只能有一个进程

启停走固定脚本,启动前检查进程数,不为 0 就拒绝。

08
Actions

行动清单

状态截至 2026-11-02 18:45;负责人按角色写,具体人选待 William 指定。

P0 已完成恢复生产路由(单进程网关);出迁移方案并发到文档站
P0 今天结算负责人:确认 16:10 删除 /settlement 是否有意;若不是,按代码恢复结算路由(需 William 同意)
P0 今天运维值班:保存网关、ZooKeeper、nginx 15:30–16:40 的日志,防止被清理
P0 本周后端负责人:与当时操作后台的同事核对 15:43–16:10 每一步的目的
P1 本周运维值班:网关启停做成固定脚本或 Jenkins 任务,带进程数检查;更新手册路径
P1 本周运维值班:每分钟真实接口探测 + 订单量骤降告警,发企微群
P1 本周后端负责人:网关后台改个人账号,改路由需第二人确认;每天只读导出路由进 Git
P2 本周后端负责人:只读审计网关鉴权(身份字段透传),待 William 批准
P2 双11 后William:按迁移方案逐步下线 ShenYu;ZooKeeper 保留
09
Evidence

附录:证据与缺口

给技术同学核对用;不含地址和密钥。

1证据来源(全部只读)

后台操作记录网关后台首页「操作记录」,共 12 条,全是今天,操作人均为共用 admin
后台现状4 个 dubbo 分组;规则 /payment 587、/user 207、/ground 68、/coach 66;接口登记 929 条
网关返回16:19 /user -107、/payment -102;16:29 前后 502;17:02 起 user、payment 正常;18:41 四个服务正常,/settlement -107
生产进程William 贴出:两个网关进程分别 16:27、16:28 启动;后台与 ZooKeeper 自 2025 年运行
Jenkins今日生产发布:结算 14:47、15:16、15:44,新后台 14:47,payment 16:00,均成功
GitLab今日合入:lianer-back !299、admin-next !26(14:45,结算数据同步)
生产库订单与开门记录按 10 分钟统计

2时间换算的依据

操作记录显示 07:43–08:10,按 UTC 加 8 小时为 15:43–16:10。依据:15:48:50 删除与 15:48:52 停单衔接;15:43 的改动在 15:44 结算发布前 1 分钟;网关后台服务的报错时间也是 UTC。

3拿不到的信息(缺口)

↑