Appearance
过载时如何控队列:Backpressure、Throughput 与 Latency
前置:怎样减少并限制下游压力:Tool Cache、Parallelism 与 Pool Capacity
核心问题:请求持续超过处理能力时,为什么无界 Queue 只会把故障推迟,Backpressure 应在哪个入口让生产者感知容量?
无界 Queue 不会消灭过载,只会把错误推迟
假设 Planner 每秒产生 200 个 Tool jobs,而下游稳定只能完成 80 个。若 Queue 没上限,前几分钟系统看起来“没有拒绝请求”,实际上 backlog 每秒增加 120。最终表现为内存上涨、任务等待几十分钟、结果过期,直到进程崩溃。
所以 capacity 设计首先接受一个事实:
长期 arrival rate 大于 service rate 时,没有任何队列长度能让系统稳定。
Queue 只能吸收短暂 burst;持续过载必须通过 backpressure、admission、降级或扩容处理。
Harness 里至少有三种不同排队点
text
API admitted Runs
→ durable Run/Broker queue
→ Runtime Ready Queue
→ Tool/Model/DB client pool它们不能共用一个“queue length”指标。Broker backlog 表示 Worker 消费跟不上;Ready Queue 增长可能表示 DAG 并行度不足;HTTP/DB pool wait 高说明下游连接容量成为瓶颈。
定位性能问题时要问:工作在哪里等待,等的是什么资源?
Backpressure 的目标是让生产者感知容量
当消费者接近上限时,可以逐层采取:
text
bounded in-memory queue
→ stop scheduling more ready nodes
→ reduce prefetch / parallel tool calls
→ delay or reject new Runs
→ degrade optional work
→ autoscale if downstream allows关键不是“所有层都设一个 semaphore”,而是把压力反馈到真正能减少新工作的地方。例如 ToolExecutor 已达到 provider rate limit 时,Scheduler 继续把 10 万 Node 放进内存 queue 没有意义。
Throughput 上升不代表系统更健康
把并发从 32 提到 128:
text
32 concurrency → 100 req/s, p95 = 1s
128 concurrency → 110 req/s, p95 = 8s吞吐只增加 10%,尾延迟却增加 8 倍,说明系统已经进入 queueing 区域。继续提高并发还可能触发 Provider 429、DB pool exhaustion 和 retry amplification。
因此容量实验至少同时记录:
text
arrival rate
completion throughput
active concurrency
queue depth / queue wait
service time
p50 / p95 / p99 latency
retry/error rate
downstream saturation只看平均 latency 很容易掩盖少数 Run 等待极久的问题。
Little's Law 给一个非常实用的直觉
稳定系统中可以用:
text
L ≈ λ × W理解排队:平均系统中任务数 L,约等于吞吐/到达率 λ 乘以平均停留时间 W。它不是 Harness 专属公式,但能提醒你:当 throughput 已到平台、任务数还在增加时,增加的主要就是等待时间。
工程上不用追求精确数学建模,也应该画出“并发/到达率 → throughput/p95/queue depth”的曲线,找出明显拐点。
Admission Control 要早于资源耗尽
对外 API 不应该等所有 Worker、DB connection、Provider quota 都耗尽后才返回 500。可以根据 tenant quota、当前 backlog、deadline 可满足性和任务优先级,在 Run 创建或调度前做 admission decision。
重要的是把“已接受但稍后执行”和“当前不能接受”表达清楚。Durable queue 能让 accepted Run 异步执行,但一旦承诺接受,就应有明确 durability/SLO,而不是无限排队。
怎么验证 Backpressure 真有效
做阶梯负载,而不是一次压到极限:逐步提高 arrival rate,每档维持足够时间,观察 throughput 是否平台、p95/p99 是否陡升、queue 是否持续增长。
再故意把某个下游降速,例如 Provider latency ×5,验证:Ready Queue 有上限;新工作被限流/排队;retry 没有把流量再放大;恢复后 backlog 能逐步下降。
正确的目标不是“永不排队”,而是过载时仍有界、可解释、可恢复。
自测
- 到达率持续高于处理率时,Queue depth、waiting latency 会怎样演化?为什么“Worker 还没满 CPU”不代表系统没过载?
- Backpressure 可以在哪里施加:入口、队列、Worker concurrency、下游限流?不同位置保护的边界有什么差别?