Skip to content

[Bug]: 请求监控会卡住,导致整个服务器卡死 #136

@zyxtoworld

Description

@zyxtoworld

部署方式

完整 Docker 方案

CPA 版本

v7.1.19

CPA-Manager 版本

v1.3.3

问题描述

Image

请求监控一直加载不出来,然后页面报超时,而且CPU和内存一直不释放,导致我的1核1G的小VPS卡死。
我按gpt给的方式改小了数据拉取的数量,但是结果又不准了,因为没完全统计。
我让gpt5.5看了一下,他说这么优化,您看下是否合理:

查了源码,结论很明确:请求监控卡,不是 SQLite 单点问题,而是 CPAM 的监控页设计成了“全量拉取 + 前端全量聚合 + 默认 5 秒刷新”。
核心链路是这样:
后端 /v0/management/usage 一次性从 SQLite 取最近 N 条事件
在 server.go (line 892):
events, err := s.store.RecentEvents(r.Context(), s.cfg.QueryLimit)
writeJSON(w, http.StatusOK, usage.BuildPayload(events))
而 QueryLimit 默认是 50000,在 config.go (line 86)。
SQLite 查询不是分页,也不是按时间范围查,是直接:
from usage_events
order by timestamp_ms desc, id desc
limit ?
在 store.go (line 758)。
原始索引只有 timestamp_ms,没有 (timestamp_ms desc, id desc) 组合索引,所以数据多时排序会更吃力。
后端 BuildPayload 把每条请求都塞进 apis -> models -> details 里返回,不是只返回汇总。
看 event.go (line 186)。
前端收到后,又把这个大 JSON 拆回明细数组。
在 usage.ts (line 304) 的 collectUsageDetailsWithEndpoint()。
然后前端对同一批 rows 重复扫描、排序、分组很多次。
在 useMonitoringData.ts (line 1909) 到 1947,依次算 summary、timeline、hourly、model、channel、failure、taskBuckets 等。
页面本体又继续算 accountRows、apiKeyRows、realtimeLogRows,在 MonitoringCenterPage.tsx (line 2241)。
最坑的是默认自动刷新是 5000ms。
在 accountOverviewState.ts (line 61)。
而 useInterval.ts (line 7) 只是普通 setInterval,没有“上一轮没结束就别开下一轮”的锁。也就是说,一旦一次刷新超过 5 秒,就会叠请求。
所以你那边会卡的真实原因是:
打开请求监控后,CPAM 每 5 秒可能拉一次大 usage 数据 + auth-files + openai-compatibility,然后前端和后端都在重复处理大量记录;1C/1G 机器一旦某轮超过 5 秒,刷新会重叠,CPU、SQLite、Docker 网络、WARP、CPA 管理接口一起被拖慢。
你之前看到 sub2api 也卡,大概率不是 CPAM 直接请求了 sub2api,而是同机资源被打满了:CPU load 飙高、Postgres/Redis/Docker DNS/WARP 都在同一台小机器上,旁边服务也跟着超时。
我们现在把 USAGE_QUERY_LIMIT=1000、pollIntervalMs=5000、batchSize=25、加组合索引,能止血。
但源码层面的根治是:
后端改成分页 + 服务端聚合,前端不要一次拿全量 details,也不要每 5 秒重复拉 auth-files。
优先级最高的改法是这三个:
/v0/management/usage/summary:SQLite 直接 count/sum/group by 返回统计。
/v0/management/usage/events?page&pageSize:明细分页。
自动刷新加 in-flight 锁:上一轮没结束,下一轮跳过。
这才是根治。现在这个请求监控页,数据一多必卡。

复现步骤

点击请求监控

关键配置

cpa:
    image: eceasy/cli-proxy-api:latest
    container_name: cpa
    restart: unless-stopped
    mem_limit: 384m
    environment:
      HTTP_PROXY: http://warp:1080
      HTTPS_PROXY: http://warp:1080
      ALL_PROXY: socks5h://warp:1080
      http_proxy: http://warp:1080
      https_proxy: http://warp:1080
      all_proxy: socks5h://warp:1080
      NO_PROXY: localhost,127.0.0.1,nginx-proxy,warp,cpa,cpa-manager,cpa-router,postgres,redis,sub2api
      no_proxy: localhost,127.0.0.1,nginx-proxy,warp,cpa,cpa-manager,cpa-router,postgres,redis,sub2api
    volumes:
      - ./cpa/config.yaml:/CLIProxyAPI/config.yaml
      - ./cpa/auth:/root/.cli-proxy-api
      - ./cpa/logs:/CLIProxyAPI/logs
    depends_on:
      warp:
        condition: service_healthy
    healthcheck:
      test: ["CMD-SHELL", "env -u HTTP_PROXY -u HTTPS_PROXY -u ALL_PROXY -u http_proxy -u https_proxy -u all_proxy wget -q -O /dev/null http://127.0.0.1:8317/healthz"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 30s
    networks:
      - net

cpa-manager:
    image: seakee/cpa-manager:latest
    container_name: cpa-manager
    restart: unless-stopped
    mem_limit: 256m
    volumes:
      - ./cpa-manager:/data
    environment:
      HTTP_ADDR: 0.0.0.0:18317
      USAGE_COLLECTOR_MODE: auto
      # Limit /v0/management/usage payload on 1C/1G hosts.
      # Without this, CPAM defaults to 50000 and the monitoring page can time out.
      USAGE_QUERY_LIMIT: 1000
      USAGE_BATCH_SIZE: 25
      USAGE_POLL_INTERVAL_MS: 5000
      HTTP_PROXY: http://warp:1080
      HTTPS_PROXY: http://warp:1080
      ALL_PROXY: socks5h://warp:1080
      http_proxy: http://warp:1080
      https_proxy: http://warp:1080
      all_proxy: socks5h://warp:1080
      NO_PROXY: localhost,127.0.0.1,nginx-proxy,warp,cpa,cpa-manager,cpa-router,postgres,redis,sub2api
      no_proxy: localhost,127.0.0.1,nginx-proxy,warp,cpa,cpa-manager,cpa-router,postgres,redis,sub2api
    depends_on:
      cpa:
        condition: service_healthy
      warp:
        condition: service_healthy
    networks:
      - net

/status 返回内容

日志

截图

No response

检查清单

  • 我已经搜索过现有 Issues,没有找到重复问题
  • 我已经确认敏感信息已经脱敏,例如 token、key、账号信息

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions