10个人同时提问只有3个坑位
开篇引言
上一篇收尾了流式生成子系列,把单个请求的故事讲得比较透了——正常路径走完 finish + done 落库关连接,被取消路径走 cancel + done 保存部分内容再关连接,资源都能干净释放。镜头始终对着一个请求,从 LLM 第一个 Token 吐出到最后一个 Token 收 束。
但是把镜头从单个请求拉远到整个集群,会看到完全不一样的压力面。
假设你在一家在线教育公司做开发,公司前段时间上了 RAG 智能客服,主要做课程咨询、退费政策、报名引导这类问题。日常流量不大,平均下来一台机器同时跑 5 ~ 10 个请求。但每周三下午 3 点,运营会推一个「限时五折」的活动短信,全网用户瞬间涌进来问优惠详情、能不能叠加优惠券、报名截止时间。促销那一刻同时来了 200 个 RAG 请求。
这时候问题就来了:
- 下游模型服务有并发上限——本地部署的 GPU 显存有限,同时跑几十个推理任务直接 OOM;在线 API 平台(如 SiliconFlow)也有并发限制,一下涌进 200 个请求,绝大多数会直接报
429 Too Many Requests - Tomcat 默认 200 个工作线程会被这些 SSE 长连接占满——单个 RAG 请求要跑 30 秒到 1 分钟,普通的 REST 接口都进不来了
你可能会想:那加个限流就行了呗,不是几行代码的事?听起来很合理,但实际跑起来你会发现问题没那么简单——QPS 限流挡不住长连接、本地 Semaphore 在多机部署下管不住总并发、直接拒绝(HTTP 429)的体验又特别差。RAG 这种长耗时 + 资源敏感 + 体验敏感的场景,需要的是另一套思路:排队。
本篇聚焦排队限流的为什么 + 整体架构 + 入队与立即抢占的同步路径。下一篇接着讲异步等待路径——抢不到许可的请求怎么等、跨集群怎么唤醒、超时了怎么给用户交代。