慢,先别瞎调。按「症状 → 看哪个值」的速查表定位,再动手。
7.1 慢了,先看这三个值
两条命令定位 80% 的瓶颈。
- 容器资源:
docker stats --no-stream,看 agent、postgres 的 CPU% / MEM% - 健康检查耗时:
curl -w "%{time_total}\n" -o /dev/null -s http://localhost:3001/health,正常 < 100ms - 对照下表锁定章节
| 症状 | 大概率原因 | 看哪节 |
|---|---|---|
| 对话整体慢、首字也慢 | LLM 上游 / 限频 | 7.4 |
| 会话列表、历史消息打开慢 | postgres / 索引 | 7.2、7.3 |
| 登录页 / 静态资源慢 | 反向代理没开缓存 | 7.5 |
| CPU 长期 > 80%,调参没用 | 该扩容了 | 7.6 |
小贴士: 调优前先备份,按数据备份与恢复打快照。每次只改一个参数,观察 1-2 天再动下一个。
7.2 PostgreSQL 内存参数
compose 自带的 postgres 是小内存出厂配置,按机器实际内存调三个值。
- 编辑 compose 里 postgres 服务的
command,按下表加参数(或挂自定义postgresql.conf) - 重启:
docker compose up -d postgres - 验证:
docker compose exec postgres psql -U aiagent -d aiagent -c "SHOW shared_buffers;"
| 参数 | 4C8G | 8C16G | 16C32G |
|---|---|---|---|
shared_buffers | 2GB | 4GB | 8GB |
work_mem | 16MB | 32MB | 64MB |
effective_cache_size | 4GB | 10GB | 20GB |
注意: shared_buffers 别超物理内存 1/4。再高反而拖慢,OS 缓存被挤掉了。
7.3 索引:高频查询走索引
列表慢、历史消息卡,多半是没命中索引。
- 开慢查询:
ALTER SYSTEM SET log_min_duration_statement = '500ms';然后SELECT pg_reload_conf(); - 跑几小时后
docker compose logs postgres | grep "duration:",挑最慢的几条用EXPLAIN ANALYZE看有没有Seq Scan大表 - 高频字段补复合索引,必须用
CONCURRENTLY不锁表
-- 示例:会话消息按时间倒序
CREATE INDEX CONCURRENTLY idx_msg_session_time
ON messages (session_id, created_at DESC);
注意: 索引不是越多越好。每个索引都拖慢写入,定期用
pg_stat_user_indexes删没用过的。
7.4 模型上游与限频
对话整体慢,多半不是本机问题,是 LLM 上游 QPS 不够。
- agent 日志频繁出现
429或「速率限制」= 上游套餐不够,去 admin 加多 key 轮询,或升级套餐 - 反向代理给对话接口加每用户限速(参考反向代理 + HTTPS
limit_req_zone),削峰避免一股脑打满 - 流式接口超时设到 300 秒(见 7.5),别让长回答中途被砍
小贴士: 首字慢 vs 总长慢。首字慢 = LLM 排队或网络;首字快但总时长长 = 回答本身太长,引导用户问得更具体。
7.5 反向代理:静态资源 + 流式
登录页慢、对话「等一会儿整段蹦出来」,都是 nginx 没配对。
- 开 gzip + 静态资源长缓存
- 对话接口必须关代理缓冲,超时拉到 300s
nginx -t→nginx -s reload
gzip on;
gzip_types text/css application/javascript application/json;
location /assets/ {
expires 1y;
add_header Cache-Control "public, immutable";
}
location / {
proxy_pass http://127.0.0.1:3001;
proxy_buffering off; # 流式对话必须关
proxy_read_timeout 300s; # 留足长回答时间
}
注意:
index.html不要长缓存,只缓存带 hash 的/assets/,否则升级后用户白屏。
7.6 何时该扩容
调参顶到天花板,单机仍跑满,就是真的该加机器。
| 场景 | 怎么扩 |
|---|---|
| CPU / 内存吃满,用户量没到天花板 | 升机器规格(如 8C16G → 16C32G),停 5 分钟切换 |
| postgres 数据 > 50GB 且查询慢 | postgres 独立成一台,agent 用 DATABASE_URL 指过去 |
| 用户量 > 500,单机仍紧 | 加 agent 实例 + 反向代理轮询,前提:postgres + uploads 已共享 |
- 扩容前压测拿基线:
ab -n 1000 -c 50 https://your-xj.com/health,记 QPS 与 P95 - 扩容后跑同样压测对比,没提升就是没扩对地方
- 动手前按数据备份与恢复备份
注意: 水平扩容 ≠ 直接复制容器。多实例 agent 必须共享同一份 postgres 与上传目录(NFS 或对象存储),否则会话和文件会分裂。设计不清就先把单机垂直顶住。