Document concurrency optimization plan

This commit is contained in:
2026-07-08 16:48:51 +08:00
parent 925ef0238d
commit 10b6de0622

View File

@@ -0,0 +1,126 @@
# 并发能力优化实施计划与过程记录
## 背景
当前用户端问答链路已经接入飞书知识库检索和大模型调用。随着真实用户进入,系统会面对多个慢外部依赖:
- 飞书 Wiki / Docx / Drive 文件读取。
- 大模型接口调用。
- SSE 长连接输出。
- MySQL 聊天记录和日志写入。
如果没有并发保护,高峰期请求可能堆满后端 worker、线程池、数据库连接或外部 API 限额,最终表现为用户端长时间无响应、`Failed to fetch`、502/500 或服务整体变慢。
## 当前问题判断
根据当前代码现状,主要风险不是单纯 worker 数量不足,而是问答主链路仍有较多同步阻塞点:
1. `/chat/completions` 会先完成飞书检索和模型完整调用,再开始返回 SSE。
2. 当前 SSE 更接近“完整答案切片输出”,不是模型真实流式输出。
3. 飞书和模型调用使用同步 `httpx`,外部服务慢时会占住后端执行资源。
4. 飞书缓存是进程内缓存,多 worker 后缓存不共享。
5. 当前没有全局并发准入和排队机制,请求超过能力边界时缺少用户可理解的等待状态。
## 优化目标
一期并发优化先达成下面目标:
1. 高峰期不让请求无限进入飞书和模型链路。
2. 用户端能看到“排队中 / 生成中 / 请求过多”的明确状态。
3. 后端能通过配置控制最大并发、最大排队数和排队超时时间。
4. 为后续 async 化、真流式、Redis 缓存和多 worker 扩展留好边界。
## 实施步骤
### 阶段 1并发准入与排队兜底
目标:先保护系统,不让过量请求直接打满飞书和模型。
实现内容:
- 后端增加问答并发管理器。
- 配置项:
- `chat_max_active_requests`:同时进入生成链路的最大请求数。
- `chat_max_queue_size`:允许等待的最大排队数。
- `chat_queue_timeout_seconds`:最长排队等待时间。
- 用户端 SSE 支持状态事件:
- `queued`:请求已进入排队。
- `generating`:请求获得执行名额,开始生成。
- `content`:模型内容片段。
- `error`:排队超时、队列满或外部服务错误。
- 队列满时直接提示“当前请求过多,请稍后再试”。
- 排队时不扣每日次数;进入真实生成并落库后再按原逻辑更新。
阶段限制:
- 第一阶段可以先使用进程内并发管理器,适合当前单 worker / 本地开发。
- 多 worker 生产环境需要阶段 4 的 Redis 全局队列,否则每个 worker 只知道自己的排队状态。
### 阶段 2模型真实流式输出
目标:用户秒见首字,减少“请求像卡死”的感觉。
实现内容:
- 模型调用支持上游 `stream=true`
- 后端边接收模型 chunk 边通过 SSE 推给前端。
- 后端累计完整回答,生成结束后再写入 assistant 消息和 AI 请求日志。
- 用户取消时尽量关闭上游模型请求。
### 阶段 3飞书与模型调用 async 化
目标:减少同步阻塞,提高单 worker 并发承载能力。
实现内容:
- 飞书读取改为 `httpx.AsyncClient`
- 模型调用改为异步。
- `/chat/completions`、RAG 构建、模型服务逐步改为 async。
- 注意数据库仍需独立评估,避免在 async 链路里长时间持有同步 DB session。
### 阶段 4Redis 全局队列与共享缓存
目标:支持多 worker / 多实例部署。
实现内容:
- Redis 存储全局并发计数、等待队列和取消标记。
- Redis 缓存飞书 token、node info、children、docx/file 文本内容。
- 多 worker 共享缓存,避免每个 worker 重复读取飞书。
- 增加缓存 TTL 和手动清理策略。
### 阶段 5worker、连接池和压测调参
目标:基于数据确定 worker 数和连接池配置。
实现内容:
- Docker/生产启动支持配置 worker 数。
- 调整 SQLAlchemy pool、MySQL `max_connections` 和网关超时。
- 压测 10 / 50 / 100 / 200 并发,记录:
- 首字时间。
- 总响应时间。
- 错误率。
- 队列等待时间。
- 飞书读取耗时。
- 模型调用耗时。
- DB 连接数。
## 当前执行计划
本次先从阶段 1 开始:
1. 新增后端进程内并发管理器。
2. 用户端支持排队状态提示。
3. 将配置项加入系统设置。
4. 验证队列满、排队中、正常生成三种路径。
5. 记录第一阶段已完成内容和遗留限制。
后续再继续阶段 2 的真实模型流式输出。
## 风险记录
1. 进程内队列不是最终生产方案,多 worker 后需要 Redis。
2. 当前模型和飞书外部 API 仍可能限流,排队只能保护本系统,不能突破外部限额。
3. 排队请求持有 SSE 连接,网关和浏览器超时时间要一起配置。
4. 真实流式前,用户端虽然能看到排队状态,但进入生成后仍要等完整模型结果才能输出内容。