λ、μ,以及队列深度
一句话总结
稳定条件只有一个:λ < μ。流入速率超过处理速率的瞬间,队列深度不会线性增长,而会爆炸式上升。
为什么需要了解这些
观察队列深度图,会发现一个奇怪现象:负载缓慢增加,队列深度却长期保持在 0 附近;超过某个点后,突然垂直上升。这不是缺陷,而是排队系统的固有性质。
当流入速率 λ 小于处理速率 μ 时,队列通常接近为空。二者越接近,为吸收瞬时波动,平均深度就越大;一旦 λ 超过 μ,队列便会无限增长。利用率 ρ = λ/μ 从 0.7 上升到 0.95 时,等待时间的差距远不止两倍。
因此,不能把 Worker 容量恰好配置为流入量的 100%。实际工作通常以 70~80% 利用率为目标,保留余量。
工作原理
把队列深度转换为延迟的工具,是 Little 定律:L = λ × W。系统中的平均项目数,等于流入速率乘以平均停留时间。反推可得 W = L / λ。队列深度为 3,000,处理速率为每秒 50 条时,当前进入的消息将在 60 秒后得到处理。完成这项计算后,“队列积压了一些”就会变成“现在提交请求的用户要等待 1 分钟”。
背压是系统在这种情况下保护自己的方法,可分为三个层次。
第一,队列上限。为队列设置最大长度,超过后向生产者返回 429。与其无限接收、以后却无法处理,不如坦诚表示当前无法接收。
第二,负载丢弃(load shedding)。优先丢弃低优先级请求。与其抓住所有请求慢慢处理,最终一起崩溃,不如快速拒绝一部分,保住其余请求,这对整体可用性更有利。
第三,调整消费者并发度,提高 μ。但并发度不能无限提高——增加 Worker 后,下游数据库或外部 API 可能成为新的瓶颈。每次都必须确认,究竟是消除了瓶颈,还是只把瓶颈移到了别处。
生产现场中的常见情况
返回 429 时,最好同时提供 Retry-After 请求头。聪明的客户端会尊重该信号,避免过早进行无谓重试。没有它,客户端会按各自的退避策略重试,多个策略又会相互叠加。
此外,队列深度告警最好根据趋势,而不是绝对值设置。有些系统深度 1,000 属于正常,另一些系统深度 10 就已经异常。“连续 5 分钟增长”是更可靠的信号。
在哪里施加背压
队列开始增长时,只有三种选择。如果一个都不选,就会发生第四种结果——耗尽内存后崩溃。
| 方法 | 放弃什么 | 适用场景 |
|---|---|---|
| 阻塞生产者(blocking) | 响应时间 | 内部流水线、批处理 |
| 拒绝新请求(429) | 部分请求 | 公共 API |
| 从最旧内容开始丢弃 | 旧数据 | 指标、日志、实时报价 |
第三种方法意外地经常是正确答案。每秒更新的报价,五分钟后才处理毫无价值。如果数据过时后就没有价值,丢弃才是正确做法。支付事件则绝不能丢弃,因此应采用第一种或第二种方法。
有界队列应当是默认选择
无限队列只会推迟问题,不会消除问题。设置上限后,问题会在生产者处暴露,而不是在队列中隐蔽累积——这样更早可见,也更容易响应。
# ❌ 무제한 — 메모리가 다 찰 때까지 아무 신호가 없다
q = asyncio.Queue()
# ✅ 상한을 두면 put 이 기다리고, 그 대기가 곧 신호다
q = asyncio.Queue(maxsize=1000)
await asyncio.wait_for(q.put(item), timeout=0.5) # 못 넣으면 거절한다
上限应根据耗尽时间确定。如果处理速率为每秒 100 条,最多允许 10 秒延迟,那么上限就是 1,000。这样,队列深度就等同于延迟预算。
何时限制并发度更准确
很多时候,限制正在处理的任务数比限制队列深度更合适,尤其是在下游脆弱时。
sem = asyncio.Semaphore(20) # 하류에 동시에 20개까지만
async def handle(item):
async with sem:
await downstream.call(item)
无论队列设置得多大,如果下游只能同时承受 20 个请求,继续发送更多请求只会压垮下游。队列是缓冲区,信号量是防护墙。 二者应配合使用。
仪表板应展示什么
큐 깊이 ← 지금 얼마나 밀렸나
소진 시간 = 깊이 ÷ 처리율 ← 이것이 경보 기준
생산율 λ 와 소비율 μ ← 둘의 차이가 추세를 만든다
거절·폐기 건수 ← 역압이 실제로 작동했는가
가장 오래된 항목의 나이 ← 지연의 최대치
最后一项尤其有用。即使队列深度相同,它也能显示旧项目是否一直无法得到处理,也就是先进先出是否已经失效。
下一次实验要做什么
使用负载生成器填充队列,按时间序列记录深度;通过 Little 定律估算等待时间;添加队列上限与 429;提高 Worker 并发度并测量处理速率改善;最后以文档形式整理稳定条件。