shared-service-maintainer-handoff-2026-11-13.md 7.4 KB

小树后台间歇超时 / 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 错误页:

    503 Service Unavailable

  • 小树运营网关 HTTP 500:Unexpected token '<', "<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-5e391e414c-20261113T124722803Z。 本次未修改公共服务源码、其他进程、公共 Nginx、DNS、负载均衡或资源优先级。

    四、请维护方交付的结果

    • 提供上述异常的根因、影响范围、负责人及修复时间。
    • 修复空响应/错误 XML 回调,并覆盖请求失败、非 200、空响应、非法 XML 等回归场景。
    • 确认并隔离公共服务与小树的健康检查/故障摘除范围,提交相关配置及状态日志的脱敏说明。
    • 处理共享资源竞争,给在线服务和批处理明确资源边界。
    • 在实际使用高峰连续观察至少 30–60 分钟:记录小树 API 的 5xx、超时率、p95/p99;证明正常业务不再频繁触发 20 秒超时。
    • 验证会员查询、课表读取及排课预检;涉及真实排课/充值写入时,用授权测试账号和幂等校验,避免重复预约、重复扣费。
    • 不影响正在上课的用户;如必须重启或切换入口,请先协调操作窗口和回滚方案。

    本说明仅包含脱敏证据摘录,未包含密码、会话、密钥、完整业务请求或学生个人信息。完整原始日志没有附带,避免敏感内容外传。