Browse Source

docs: prepare shared-service incident handoff for maintainers

彭峰 4 hours ago
parent
commit
9204ccc0ab
1 changed files with 106 additions and 0 deletions
  1. 106 0
      docs/operations/shared-service-maintainer-handoff-2026-11-13.md

+ 106 - 0
docs/operations/shared-service-maintainer-handoff-2026-11-13.md

@@ -0,0 +1,106 @@
+小树后台间歇超时 / 503:请维护方优先处理共享服务稳定性
+证据日期:2026 年 11 月 13 日;以下时间均为北京时间(UTC+8)
+说明:这是当晚排查记录,不代表接收本文时的实时状态。
+
+一、请优先处理的事项
+
+小树管理后台的会员管理、课表读取和新增排课页面间歇出现“0 Unknown Error”或超时,已影响日常排课。小树侧已完成内部访问改为本机直连、读取请求有限重试等修复,但共享主机资源竞争、公共服务异常及入口健康检查仍需维护方核查处理。
+
+请安排负责人优先排查下列三项,并反馈原因、修复时间与验证结果:
+1. 公共服务的 XML 回调异常及进程重启。
+2. 入口健康检查是否把公共服务故障扩大到小树等独立服务。
+3. 共享主机资源竞争,避免批处理影响交互请求。
+
+二、已确认的证据
+
+【A:公共服务异常与重启记录】
+PM2 采样:
+- 公共进程名 server,PID 14550,最近启动于 20:35:47,restart_time=53。
+- 小树进程名 xiaoshu,PID 25381,最近启动于当天 10:07:32,restart_time=6;排查及小树修复过程中 PID 未变。
+注意:上述 restart_time 是 PM2 累计计数,不是本次故障时段的重启次数。请维护方对照完整 PM2 时间线核实异常与重启的对应关系。
+
+错误日志:
+/root/.pm2/logs/server-error__2026-11-13_20-35-54.log
+
+关键堆栈:
+TypeError: Cannot read properties of undefined (reading 'xml')
+    at /opt/future-server/cloud/user/auth-route.js:539:32
+    at Request._callback (/opt/future-server/cloud/user/auth-route.js:538:6)
+    ...
+    at Request.onRequestError (.../request/request.js:877:8)
+
+源码对应位置(535–540 行):
+Request(
+  { url: orderUrl, method: 'POST', body: JSON.stringify(oederData) },
+  function (err, response3, body) {
+    xml2jsparseString(body, { async: true }, function (errors, resp) {
+      console.log('订单状态', resp.xml)
+      console.log('status', resp.xml.trade_state)
+
+这里在读取 resp.xml 前没有处理请求错误、XML 解析错误或空响应。请修复异步回调的错误处理,保证上游异常只结束当前请求,不造成进程级异常;同时核查 XML 请求体和 Content-Type 是否符合上游协议。不要仅靠重启恢复。
+
+【B:入口健康探测持续连接拒绝】
+日志:/var/log/nginx/error.log
+本次读取的末尾约 64 KB 日志中,有 185 条匹配的 /health 上游连接拒绝记录;这是抽样,不是全天总数。
+
+样例(省略请求流水号):
+2026/11/13 20:31:26 connect() failed (111: Connection refused) while connecting to upstream,
+client: 10.0.1.160, server: _, request: "GET /health HTTP/1.0",
+upstream: "http://127.0.0.1:7337/health"
+
+同类记录持续出现在该日志片段中,最后样例时间为 20:36:37。
+同一排查期间,小树公网链路还捕获了:
+- HTML 错误页:<html><body><h1>503 Service Unavailable</h1>
+- 小树运营网关 HTTP 500:Unexpected token '<', "<html><bod"... is not valid JSON
+
+需要核实的关系:公共进程/7337 健康检查失败,是否导致负载均衡摘除整个共享节点,进而使本来仍在运行的小树返回 503。现有证据显示这些现象并存,但尚未取得实际对外入口的转发、健康检查配置及状态变更日志,不能把这一传播链路写成已确认根因。
+
+小树已核对的本机链路:
+- /etc/nginx/sites-enabled/server-xiaoshu-443.conf:443 → 本机 7458。
+- /etc/nginx/sites-enabled/server-xiaoshu.conf:7458 → 127.0.0.1:10337。
+- 采样时小树 10337 的 /health 返回 200。
+请重点核对外层入口如何区分 7337 与 10337 的健康状态,避免一个服务失效连带摘除其他健康服务。不要简单将所有健康检查改为固定 200 来掩盖实际故障。
+
+【C:共享主机负载较高】
+20:35:28 采样:
+- CPU:2 核。
+- 1 / 5 / 15 分钟 load average:8.98 / 9.40 / 8.73。
+- 内存约 4 GB,采样时 free 约 1.7 GB;本次没有足够证据认定发生 OOM。
+- 进程 CPU 时间增量采样中,多个 python3.9 批处理及公共 Node 进程较高。
+- 对应 Python 任务包含 /opt/ksf-unified-runtime-hotfix-20261109-r1/server/voc-library/voc_db.py;当时采样 PID 包括 14106、14360、14469。PID 可能已变化。
+
+请按任务归属核对并发、重复任务、调度和资源配额,保护小树在线交互服务;不要在未确认任务用途前直接终止其他业务。load average 不等于 CPU 利用率,请结合 CPU、I/O、运行队列和限流情况进一步确认瓶颈。
+
+【D:小树用户链路的实际表现】
+- 后台读取限时为 20 秒,原先连读取超时也显示“结果待核对”,易与提交失败混淆。
+- 按前端实际参数 source=database 测得:课表读取 9.455–13.222 秒;会员列表 4.135–4.291 秒。
+- 另一次未固定 source=database 的混合来源诊断,课表为 37.959 秒;该样本不能当作前端同条件基线。
+- 数据库当时只读采样未见锁等待;这不代表所有时段都没有数据库问题。
+- 证书有效期为 2026-11-05 至 2027-02-03;抽样 OPTIONS/CORS 正常,未复现证书过期。
+
+三、小树已经完成的修复,请维护时保留
+
+1. 仅修改小树专属配置 /opt/future-server/config/config.xiaoshu.json:
+   parse.serverURL = http://127.0.0.1:10337/parse
+   parse.publicServerURL = https://server.xiaoshu.pro/parse(保持原值)
+   同步更新小树当前进程的 SDK 配置,无需重启;其他配置与凭据未变。
+   目的:小树服务访问自身数据接口不再绕行公网入口。
+2. 后台明确的只读操作遇到 HTTP 0/502/503/504 时,延迟 500ms 重试一次。客户端超时不自动重试,排课、充值等写操作不自动重复执行。
+3. 区分读取错误和提交结果不确定;失败后保留草稿。
+4. 线上验收通过:连续 9 次正式读取成功;浏览器注入单次断连/503 后恢复成功;连续读取失败后表单草稿保留;真实排课预检成功。测试没有创建预约、充值或扣费。
+5. 小树内部改动后,课表样本 6.455–11.620 秒、会员样本 2.015–3.521 秒。负载随时间变化,此数据不用于宣称严格的性能提升比例,也不证明共享故障已消除。
+
+小树静态版本:admin-reliability-5e391e414c72-20261113T124722803Z。
+本次未修改公共服务源码、其他进程、公共 Nginx、DNS、负载均衡或资源优先级。
+
+四、请维护方交付的结果
+
+- 提供上述异常的根因、影响范围、负责人及修复时间。
+- 修复空响应/错误 XML 回调,并覆盖请求失败、非 200、空响应、非法 XML 等回归场景。
+- 确认并隔离公共服务与小树的健康检查/故障摘除范围,提交相关配置及状态日志的脱敏说明。
+- 处理共享资源竞争,给在线服务和批处理明确资源边界。
+- 在实际使用高峰连续观察至少 30–60 分钟:记录小树 API 的 5xx、超时率、p95/p99;证明正常业务不再频繁触发 20 秒超时。
+- 验证会员查询、课表读取及排课预检;涉及真实排课/充值写入时,用授权测试账号和幂等校验,避免重复预约、重复扣费。
+- 不影响正在上课的用户;如必须重启或切换入口,请先协调操作窗口和回滚方案。
+
+本说明仅包含脱敏证据摘录,未包含密码、会话、密钥、完整业务请求或学生个人信息。完整原始日志没有附带,避免敏感内容外传。