Files
pikasTech-unidesk/docs/MDTODO/details/sub2api-upstream-reliability/R2.18.2_Task_Report.md
T
pikastech 31106a2ee0
Pipelines as Code CI / hwlab-web-probe-sentinel-nc01- Success
Pipelines as Code CI / platform-infra-gitea-nc01- Success
Pipelines as Code CI / unidesk-host- Success
chore: 合并并行工作区更新
2026-07-18 05:36:52 +02:00

3.6 KiB
Raw Blame History

R2.18.2 任务报告

结论

Sub2API 评分查询会给 PK01 带来显著的周期性 CPU 峰值,尤其是 ApiState 每 10 分钟执行的 8 小时账号评分。它不足以解释持续高 CPU,但与生产流量或人工刷新重叠时,足以把 2 vCPU 的 PK01 推近 90% 以上。应把评分、去重、TTFT 分位数、成本和 failover 关联迁到 NC01;PK01 只保留原生分页查询和最小必要数据库聚合。

实测证据

  • PK01 为 2 vCPU、约 4 GiB 内存;调查结束时 load average 约 0.84/0.60/0.46Sub2API 基线约 2% 至 4%Redis约 0.2% 至 0.4%。
  • 原生 ops diagnosis --time-range 1h 约 2.4 秒,属于较轻的 dashboard 聚合。
  • runtime errors --all-groups --since 1h 约 17.1 秒;远端 job 约 16.0 秒。查询期间 Sub2API 峰值约 13%,远端 Python 约 9%PostgreSQL 活动连接通常 1 至 2 个。
  • 单组 runtime errors --group unidesk-codex-pool --since 8h 约 31 秒。采样观察到:
    • PostgreSQL 单 backend 瞬时约 70.2% CPU
    • Sub2API 容器约 12.5% 至 22.2% CPU
    • PK01 远端 Python 聚合约 8% 至 11.3% CPU
    • Redis保持约 0.2% 至 0.4%,不是主因。
  • ApiState 最近一次生产评分从 2026-07-17T09:06:02.920Z 到 09:06:58.786Z,耗时约 55.9 秒。
  • ApiState 配置为 8 小时窗口、10 分钟刷新;实现先调用一次 --all-groups,再以并发 2 对全部组执行详细评分。当前有 3 个组,两个 OpenAI 组各有 13 个账号。

根因

  • UniDesk runtime errors 通过 runRemoteCodexPoolScript 把完整 Python 脚本放到 PK01 执行。
  • 详细评分在 PK01 内完成以下工作:
    • 每组读取 dashboard overview、账号可用性和并发;
    • 分页读取 request-errors
    • 对 7 类 system-log marker 分别分页搜索;
    • 对组内每个账号逐页读取 /api/v1/admin/usage?page_size=100
    • 必要时读取容器日志回退;
    • 在 PK01 Python 中完成事件关联、TTFT 分位数、评分和成本聚合。
  • 8 小时窗口当前约 1 万次请求,仅 usage 的理论分页下限就超过 100 页;逐账号分页会进一步增加请求次数。
  • ApiState 的并发 2 会让两个 OpenAI 组的重查询同时落到 PK01。共享账号最终虽在 NC01 合并为一行,但组内 usage、错误和日志查询仍分别执行。
  • Web 人工刷新当前由 API 进程直接执行,Temporal 周期刷新由 worker 执行;两者没有跨进程 single-flight,存在重叠风险。

优化方案

  1. 保留 Sub2API 原生 admin/ops API 和数据库为事实源,不改 Sub2API 源码或版本。
  2. 将受控 CLI 拆为“PK01 薄采集 + NC01 本地聚合”:
    • PK01 只执行登录、原生分页读取和最小字段裁剪;
    • 原始分页结果返回 NC01
    • 账号去重、错误归因、failover join、TTFT 分位数、评分、成本和表格渲染全部在 NC01 执行。
  3. usage 改为每组/窗口一次分页,不再按账号逐个分页;在 NC01 按 account_id 分桶。
  4. 在 NC01 保存 8 小时滚动缓存和原生记录高水位,后续刷新只拉增量;窗口过期数据本地剔除。
  5. ApiState 保留 Temporal 为唯一周期刷新 owner;人工刷新也提交到同一 Temporal 路径并合并进行中的刷新,避免 API 与 worker 重叠。
  6. 迁移完成前的保守缓解是把详细组查询并发从 2 降为 1,并阻止人工刷新与周期刷新重叠。该措施只削峰,不解决远端聚合根因。

边界

  • 本轮仅只读调查和源码分析。
  • 未修改 Sub2API 源码、版本、runtime、YAML、外部哨兵或生产运行面。
  • 未停止任何进程。