diff --git a/deploy/README.md b/deploy/README.md index 24fc80cad..b2e4f483f 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -564,10 +564,6 @@ docker compose -f deploy/compose.yaml up -d --no-build --wait 升级后通过管理端版本接口或容器 image digest 确认运行实例的版本和 revision -管理端请求默认等待 120 秒。直接构建前端时可通过进程环境 `VITE_API_TIMEOUT_MS` 指定毫秒数, -例如 `VITE_API_TIMEOUT_MS=180000 pnpm --dir frontend build`,取值须为正整数。 -该值在构建时写入静态资源,修改后需要重新构建和部署前端。单个请求显式指定的时限仍优先 - 构建元数据通过一次性进程环境传入: ```bash diff --git a/docs/plans/413-postgresql-capacity.md b/docs/plans/413-postgresql-capacity.md deleted file mode 100644 index 725bc1094..000000000 --- a/docs/plans/413-postgresql-capacity.md +++ /dev/null @@ -1,81 +0,0 @@ -# PostgreSQL 3100 万请求优化与验收 - -本报告对应 [Issue #413](https://github.com/zyycn/codex-proxy-rs/issues/413),范围为大数据量下的统计、请求分页、账号用量、分组费用与额度预测 - -3100 万条源请求、窄事实和完整汇总已构建并独立对账。当前 HTTP 矩阵执行 167 次请求,包含 145 次合法业务请求、22 次预期参数或权限拒绝,未出现超时或非预期失败。按实际注册路由计,84 条已有通过记录、70 条未覆盖、6 条不适用;不宣称全接口或长期负载验收通过 - -## 问题与实现边界 - -原账号用量读取在命中事实超过 10 万条时拒绝查询;其他统计的事实回退与汇总读取也有固定行数门槛。仅放宽门槛会继续放大应用端逐行合并、深页 OFFSET 和预测窗口排序的成本 - -实现继续使用原生 PostgreSQL、现有窄事实、十五分钟/小时汇总和投影 Worker: - -- 账号与 Key 的必要模型联合维度进入共享汇总,完整桶和精确边界在数据库内聚合,不以命中数据量拒绝查询 -- 账号窗口、用量排序、分组费用和分页计数在同一读快照补齐待投影修改与删除,保留精确总数、金额及未知值语义 -- 请求深页通过时间分段定位,错误列表合并两类来源后保持稳定排序 -- 预测使用开始时间与完成时间二维汇总,累计量保留完整窗口,Provider 文档独立有界采样 -- 投影在同一事务撤销旧贡献并加入新贡献;普通更新维护构建前缀,不反复重启整个桶 -- 观测操作与前端默认保护时限为 120 秒,可分别配置;30 秒为优化方向,不能将提高超时时限当作查询提速 - -使用记录搜索支持密钥、账号与模型,不匹配请求 ID;请求 ID 的显式精确筛选仍保留。汇总、洞察和诊断不接受搜索参数,管理观测接口不接受路由分组筛选 - -当前合同与职责见 [API 参考](../api.md)、[系统架构](../architecture.md#10-观测与后台任务)与[部署配置](../../deploy/README.md),本报告不重复字段清单 - -## 环境与样本 - -| 项目 | 实际条件 | -| --- | --- | -| 数据 | 31 天、3100 万条合成源请求;50 个账号、100 个 Key、20 个模型、10 个分组 | -| 时间范围 | `2026-09-12T04:45:00Z` 至 `2026-10-13T04:45:00Z` | -| 数据库 | PostgreSQL 18.6,容器限制 4 CPU、4 GiB 内存,持久磁盘 | -| 主要参数 | shared_buffers 512 MiB、work_mem 16 MiB、max_parallel_workers 8、max_parallel_workers_per_gather 2、JIT 开启 | -| 持久性 | fsync、full_page_writes、synchronous_commit 均开启 | -| 应用 | release 构建;核心轮次重启应用清空应用缓存,16 个查询客户端并发 | -| 其他轮次 | 剩余只读接口 4 并发;合成配置写入、鉴权及本机 Provider 场景串行执行 | -| 缓存边界 | 未清空数据库与宿主文件缓存,应用冷缓存不等于数据库冷缓存 | - -造数与离线汇总构建使用的临时资源配置已恢复,搜索索引试验已撤销。3100 万条容量基线不是生产 Worker 全量回填吞吐的测量结果;生产投影的正确性通过真实源表回归及样本对账验证 - -## HTTP 结果 - -以下为当前矩阵中的单次短样本,不能推断稳定的 P95/P99。并发样本包含资源竞争,不能与隔离单请求耗时直接当作前后优化对照 - -| 场景 | 耗时 | -| --- | ---: | -| 用量明细宽范围模型前缀搜索 | 32.63 秒 | -| 账号用量降序 | 20.50 秒 | -| 账号最近使用降序 | 20.39 秒 | -| 账号额度预测 | 19.94 秒 | -| Key 维度诊断 | 18.46 秒 | -| Dashboard 概览 | 12.30 秒 | -| 账号维度诊断 | 10.82 秒 | -| 用量洞察 | 6.20 秒 | -| 用量汇总 | 6.17 秒 | -| 用量中间页 | 3.60 秒 | -| 用量首/尾/超尾页 | 3.46/1.63/1.39 秒 | -| 错误列表第 6200 页 | 1.70 秒 | - -宽范围搜索命中大量明细,32.63 秒超过 30 秒优化期望,但未触发 120 秒保护时限。本次保留该性能局限,不再为此扩展索引或引入其他存储系统 - -正确性核对覆盖源请求总量、Token、费用、主要筛选组合、诊断分母及分页结果。移除的搜索与分组参数按预期返回 400,权限负例按预期返回拒绝;这些负例不计作合法容量查询通过 - -## 回归与自审范围 - -- 超过 10 万条真实源请求经过生产 Worker,验证账号/Key 汇总、热点边界和未知 Token;锁住窄事实表时,干净完整桶仍可读取 -- 待投影跨账号/模型/时间桶修改、删除、重复投递、写入失败回滚及构建前缀持续更新 -- 精确分页首中尾页、超尾页、跨时间段与同时间戳排序,两类错误来源合并 -- 预测微秒边界、同完成时间、截止时间、缺失费用、恢复请求、重建与待投影补差 -- 连接排队计入总预算,超时与取消后的事务回滚及连接归还仍持有查询名额 -- 分组费用沿用当前成员关系;账号窗口的 Token 兜底与普通统计的未知值口径分别保留 -- 投影与极值重算共用维度定义,已删除请求 ID 搜索捷径及淘汰的逐行读取映射 -- Rustfmt、相关 Store/Admin/API 回归、严格 Clippy、架构边界、迁移冻结清单、前端类型构建与 ESLint 对应实际最终工作区执行 - -页面仅调整搜索提示;按本次任务要求不提供截图 - -## 升级与验证局限 - -迁移 0030/0031 增加统计字段和索引,将既有时间桶排入可恢复重建,不清空窄事实或重置已完成的源投影游标。重建中的桶走事实回退,索引创建与桶重建仍需要额外 I/O、磁盘空间和时间;未完成生产环境在线升级的时延与负载验收 - -本次收尾聚焦 3100 万请求瓶颈,不再扩展外围插件、OAuth、备份和升级场景。数据库冷缓存、长期持续负载、生产 Worker 全量回填性能及未覆盖外部集成保留为验证局限;小规模生命周期回归不等于相同场景的 3100 万级持续写入验收 - -临时造数、HTTP 驱动、SQL 计划及逐请求记录保存在忽略跟踪的 `.runtime/capacity`,不进入工程提交。完整请求与路由结果为 `http-31m-latest.json`/`http-31m-latest.md`,原失败轮次分别保留,最终检查日志使用 `final-*` 前缀 diff --git a/frontend/env.d.ts b/frontend/env.d.ts index e4e07997e..eec606cdc 100644 --- a/frontend/env.d.ts +++ b/frontend/env.d.ts @@ -1,9 +1,5 @@ /// -interface ImportMetaEnv { - readonly VITE_API_TIMEOUT_MS?: string -} - declare module '@fontsource-variable/inter' declare module '@fontsource-variable/jetbrains-mono' diff --git a/frontend/src/api/constants.ts b/frontend/src/api/constants.ts index b0f5ea787..5b7386cfe 100644 --- a/frontend/src/api/constants.ts +++ b/frontend/src/api/constants.ts @@ -1,6 +1,2 @@ export const API_BASE_URL = import.meta.env.DEV ? '/dev' : '' -const timeout = Number(import.meta.env.VITE_API_TIMEOUT_MS ?? 120_000) -if (!Number.isSafeInteger(timeout) || timeout <= 0 || timeout > 2_147_483_647) { - throw new Error('VITE_API_TIMEOUT_MS must be a positive 32-bit integer') -} -export const API_TIMEOUT_MS = timeout +export const API_TIMEOUT_MS = 120_000