RAG 服务过载时,先给每一段外部调用设容量 📅 发布时间:2026/8/24 21:13:36 👁 浏览次数: RAG 服务过载时先给每一段外部调用设容量一次题解请求可能包含嵌入、向量检索和模型生成。它们的吞吐不同入口并发不能直接当作服务能力。为每一段设置独立的并发上限和等待上限满载时返回可解释的繁忙状态或较弱的结果比让请求无限排队更可靠。select { case sem - struct{}{}: defer func(){ -sem }() case -ctx.Done(): return Result{}, ctx.Err() default: return Result{}, ErrBusy }令牌桶适合限制到达速率信号量适合限制在途数量两者解决的问题不同。缓存也应按命中率、失效和权限隔离来评估不能成为绕过限流的入口。压测要分别测量检索和生成耗时、队列等待、拒绝率与恢复时间并写明模型、数据集和并发模型。只有在可接受错误处理下取得的延迟才有意义。容量按最慢阶段拆开算嵌入、检索和生成经常由不同的服务承担。生成阶段占满时即使检索仍有余量也不应继续把所有请求塞进后续队列。为每个阶段设置独立的信号量能把瓶颈暴露在对应指标里全局入口限制只负责保护服务整体不能替代阶段限制。代码中的default表示立即拒绝适合交互请求需要快速反馈的场景。若业务允许短暂等待可以增加一个很小的排队窗口但必须仍然监听ctx.Done()。无限等待是反例客户端已经放弃时排队任务仍会占着内存和连接过载恢复会越来越慢。缓存要服从权限和失效规则缓存键至少要包含会影响结果的检索参数、知识库版本和访问范围。不能只按问题文本命中否则两个权限不同的用户可能复用不该看到的结果。对于更新频繁的索引还要允许失效或带版本读取把缓存命中率当作唯一目标容易得到陈旧答案。验证时逐步提升某一阶段的模拟延迟观察请求是在正确的位置被拒绝、超时还是降级。恢复延迟后再确认信号量已释放、队列长度回落、后续请求能正常进入。这样得到的是过载行为的证据而不是单个平均延迟数字。3. 降级结果也要有明确语义过载后不能生成完整答案时服务可以只返回检索片段、提示稍后重试或转到较便宜的模型。但每一种降级结果都要让调用方看得出来不能把“没有检索到”与“系统来不及检索”混成同一种空回答。前端据此决定是否展示重试入口后端也能分别统计质量问题和容量问题。降级链路本身应有上限。某个阶段失败后继续尝试三个备用服务可能把原本局部的压力扩散出去。把优先级、触发条件和停止条件写清楚并在压测中观察切换后每个依赖的负载才能确认保护措施没有制造新的拥塞。4. 排队信息应当对用户有用请求被拒绝时返回“系统繁忙”比一直转圈更诚实但信息还可以更具体是否建议稍后重试、当前是否已经降级、同一请求是否安全重发。不要暴露内部队列长度或机器信息却要让客户端知道它该等待、重试还是改走离线任务。服务端对拒绝也要记账。按入口、阶段和租户维度统计能分辨是某个热点功能打满还是总容量不足。容量扩容前先看这些数据避免用更多机器掩盖一个没有限流的调用方。