多租户 Agent 调度设计:公平队列、预算预留与过载保护 @ Lin | 2026-10-21T08:00:00+08:00 | 4 分钟阅读 | 更新于 2026-09-16T08:00:00+08:00

在共享模型配额下区分准入、排队和执行,避免一个租户的长任务耗尽其他用户的服务能力。

有全局限流,仍可能没有租户公平性

模型网关同时服务三个团队:A 持续提交文档分析长任务,B 偶尔查一个工单状态,C 批量整理历史工单。即使总并发严格限制在供应商配额内,A 仍可能长期占满许可,让 B 的轻量请求一直等待。

全局限流保护下游,公平调度决定谁先得到有限资源。两者是不同层次的问题。只给每个租户设置相同请求次数,也无法处理单次任务从几百到几万 token 的成本差异。

可以把链路拆成准入、排队、资源预留和执行四个阶段,分别定义失败与恢复语义。

准入先限制积压,再谈优先级

请求进入系统时,先检查身份、任务类型、输入大小和租户未完成任务数。不符合约束的请求在入口明确拒绝,或者转为用户知晓的离线任务,不能无限堆进消息队列。

建议区分交互问答和批处理队列。交互任务设置较短的最大排队时间,批任务允许更长等待但不无限延续;等待人工审批的任务暂时释放模型执行许可。

租户优先级来自服务配置和业务策略,不能从模型生成的“紧急”标签直接决定。用户输入“最高优先级”也不应自动获得管理员级资源份额。

用成本单位而不是任务个数分配机会

一种候选方法是按租户维护调度积分,每轮按权重补充额度,并用估计成本扣减。下面是调度逻辑示意,不是可直接使用的完整算法:

每个调度轮次:
  对有积压的租户补充 quantum × weight
  对当前候选任务估算资源成本
  若租户积分足够且全局许可可用:
    原子预留许可和预算
    扣减积分并开始执行
  否则保留任务,继续考虑其他租户

成本可以用归一化 token 或其他业务定义单位,但必须在同一队列中可比较。输入 token 可提前估计,输出和工具步骤则需要设置上界,并在结束后结算。

假设 A、B 每轮各获得 100 单位,A 队首任务估计需要 300,B 的任务只需 50。A 在积分积累期间,B 可以继续处理;A 获得足够积分后也应有机会执行。这是机制示例,不代表某个固定公平率。

积分上限要允许最大合法任务最终获得资格,否则大任务会永久饥饿。也可以为超大任务设置独立队列或拆分执行,避免它占住租户队首。

预算预留需要跨实例一致

如果两个 Worker 同时看到“剩余预算 100”,各自启动一项成本 80 的任务,最终会突破预算。检查和扣减必须在同一原子操作中完成,可以使用数据库条件更新或经过验证的配额服务。

预留记录至少包含 taskId、租户、额度、状态和租约。模型调用尚未开始便失败时可以释放;已经开始但未拿到完整 usage 时,不能直接按零消耗回收,应采用保守估计或等待对账。

子 Agent 继承父任务的预算范围,不能各自向全局重新申请一份不受父任务限制的额度。否则主任务表面上只有一次请求,实际支出却随分支数量增长。

Java 的 Semaphore适合控制单进程内同时占用的许可;即便启用公平模式,也不等于实现跨实例的租户加权公平,更不自动处理 token 预算。

模型长调用无法轻易抢占

任务开始后,通常不能像 CPU 时间片一样随意暂停并恢复远端生成。公平性主要发生在新步骤获得执行资格时,而不是每秒强行切走正在生成的请求。

因此长任务需要限制单步输出、设置截止时间,并在步骤之间重新排队。对可以分块的文档分析,分块既提供恢复检查点,也提供其他租户获得执行机会的边界。

取消请求应沿执行链传播,但只有确认资源不再使用或进入明确结算规则后,才回收相应许可。过早释放会造成实际并发超限;永久不释放则会让系统逐渐失去容量。

公平和利用率之间需要明确取舍

为每个租户永久保留独占槽位可以降低干扰,却可能在租户空闲时浪费资源。共享剩余额度能提高利用率,但借用需要在后续步骤可回收,不能承诺已开始的不可抢占调用立刻让出容量。

还需要处理低优先级任务的等待上限。可以采用等待时间加权或定期保障份额,但要避免用户反复取消、重建任务来刷新排序优势。

如果供应商突然降低配额,应减少新步骤启动速度,并对超出排队时限的任务给出明确结果。继续按旧吞吐率接收请求,只会把压力积累到未来。

实验应该观察每个租户

在同一总配额下设置三组负载:一个租户持续高流量、一个租户偶发短任务、一个租户只提交大任务。记录各租户吞吐、最长等待、完成率、实际成本和全局利用率。

再让 Worker 在预算预留后崩溃,确认额度会在合理条件下恢复;模拟迟到的结算事件,确保不会重复退款或重复扣费。用操作 ID 去重,预算账本和任务状态保持可追溯关系。

可以延续此前的容量规划方法与成本预算设计。公平调度的结论应说明哪些租户得到保障、代价是什么,而不是只展示全站平均延迟下降。

© 2019 - 2026 Lin 的博客

Powered by Hugo with theme Dream.

avatar

Lin 的博客 A merry heart goes all the way.

关于我

Lin 的 ❤️ 博客

技术专题:Java Agent 工程化:从知识库问答到可靠业务执行。围绕 RAG、工具治理、任务恢复与 Java 平台架构整理设计思路和验证方法。

记录一些 🌈 生活上,技术上的事

  • 🛠️ 技术阵地: 深耕 Java 开发 ,目前向 AI 应用领域探索与拓展。这里主要记录我从后端架构到 AI 赋能的进阶之路、技术思考以及日常的 debug 血泪史。始终致力于写出优雅且没有 bug 的代码(尽量)。
  • 🌈 生活侧写: 偶尔脱下极客的外衣,我也会在这里分享生活中的灵光一现。不管是好用的效率工具,还是周末的一场骑行,都是构成我真实生活的一部分。