开始前,会这些就够了
- 理解平均数和每秒速率
遇到不熟悉的词,先看这 4 个解释
- 重试
- 遇到可能只是暂时性的失败后,按预定规则再次尝试同一项操作;规则通常限制次数、等待间隔和总耗时,也要考虑重复执行会不会多做一次业务。
- 缓存雪崩
- 大量缓存同时失去作用后,本来被缓存接住的请求集中转到后端,可能让数据库和依赖服务接连过载;常见诱因是许多条目在相近时间到期。
- 吞吐量
- 单位时间内处理的工作数量,例如每秒完成多少请求或每分钟处理多少任务;比较前要写清统计窗口、工作类型,以及失败的尝试是否也被计入。
- 队列
- 把暂时不能立即处理的任务或消息先保存起来,等处理方取走;它把提交与执行分开,可以缓冲短时忙碌,但等待中的数量也会占用资源。
假设图片处理服务积压了两千个任务,同事拿“每秒进来一百个”一除,宣布二十秒就能清完。这个算式很诱人,却没有说明处理速度,也没有说明新任务会不会继续到来。队列是存量,进入速率和完成速率是两股流,三者不能混成一个数字。
先规定哪些任务算在里面
Little 法则常写成 L = λW:长期平均在系统里的任务数,等于进入该系统的有效平均速率,乘以任务在其中的平均停留时间。比如假设稳定服务每秒完成一百个请求,每个请求从接纳到完成平均停留零点二秒,那么系统内平均约有二十个请求。
这二十个包含等待和正在处理的请求,不等于必须开二十个工作线程。如果只统计排队区,W 也只能使用排队等待时间。被入口拒绝而未进入系统的请求,不能计进这里的有效到达率;把不同范围的数据相乘,单位可能正确,意思却已经错了。
用三个任务核对“人数乘时间”
下面是三个假设任务的进入、离开时间,单位为秒。程序先按每段时间有多少任务留在系统里计算平均数量,再独立计算吞吐量和平均停留时间。观察窗口从零到六秒,开始前为空,结束时全部离开,因此没有只算了一半的任务。
这个有限窗口的完整记账可以直接核对等式,不需要假定随机到达或固定处理时长。实际监控窗口常切过任务:有些在窗口前进入,有些结束后才离开。如果只拿窗口内完成的任务计算平均停留时间,未必能与窗口内的平均任务数量对应。使用长期稳定的平均值是常见办法,同时仍要检查这些数量和时间是否来自同一系统范围,并采用可比的观察时段。
jobs = [(0, 2), (1, 4), (2, 6)]
points = sorted({t for job in jobs for t in job})
area = 0
for left, right in zip(points, points[1:]):
middle = (left + right) / 2
count = sum(start <= middle < end for start, end in jobs)
area += count * (right - left)
window = 6
L = area / window
rate = len(jobs) / window
W = sum(end - start for start, end in jobs) / len(jobs)
print("L", L, "rate", rate, "W", W)
print("rate * W", rate * W)
怎样运行:Python 3.10+;保存为 queue_demo.py,运行 python queue_demo.py。
运行后对照结果
L 1.5 rate 0.5 W 3.0
rate * W 1.5
持续积压时,先看进出差额
假设每秒接纳一百个任务,只能完成八十个,没有取消或丢弃,积压就每秒增加二十个。此时不能把某一刻的任务数量塞进稳定平均公式,声称系统已经达到平衡。即使增加队列容量,也只是允许更多任务继续等着,并没有提高完成速率。
若新任务停止进入,且处理速度一直稳定为每秒八十个,才可以用剩余工作量估算清空时间;任务大小不同、重试、多个队列优先级或处理速度变化,都会影响结果。任务数量相同也不一定工作量相同,一张小图与一段长视频就不能等价计算。
同时观察任务数量和最老任务
平均数量可能掩盖少数任务一直被饿着的情况,所以还要看最老任务已经等多久、完成吞吐量、失败重试数量,以及新旧任务是否争用同一资源。Little 法则是核对平均量关系的工具,不会告诉你某一个请求何时完成,也不会自己找出瓶颈。
需要缩短等待时,可以减少接纳、提高实际处理能力,或减少每个任务的工作量;若改成丢弃、合并或取消,也要把这些离开方式记在统计里。先把“谁进来、谁离开、在里面多久”记明白,扩容建议才有可以检验的依据。
记住这三点
- L、λ、W 必须使用同一个系统范围和兼容的统计口径。
- 瞬时积压与长期平均在途数量不是同一个量。
- 队列更大不会自动增加完成能力,还要观察任务年龄。
别把例子用过头
- 本例的完整有限窗口避免了边界任务,线上窗口通常需要额外处理。
- 法则不直接给出个体等待时间或尾延迟,也不替代容量模型。
自己试一小步
如果观察只到第四秒,而第三个任务尚未完成,怎样记录才不会漏算它的占用?
- 在纸上把三个任务画成横向时间段。
- 将窗口截为零到四秒,分别计算窗口内占用面积和已完成任务平均耗时。
- 列出两组数字不再能随意配对的原因。
做到这些,就算完成
- 区分完整停留时间与窗口内占用时间。
- 说明队列范围是否包括正在处理的任务。
- 没有用一个瞬时队长证明系统长期稳定。
查原始资料
想确认一个细节,先看这份资料对应的部分,不必从头读完所有文档。
- Class 3: Capacity Lecture (新标签页)↗
PDF 第 17 页展示 L = λW、系统平均数量、平均停留时间与流量平衡;讲义区分确定性和突发到达。
- Queueing Lecture Notes (新标签页)↗
PDF 第 3–4 页分别定义系统内数量与排队数量、总停留与排队等待,并列出队列模型的稳定性前提。
找一份资料继续练
先选一项,按下面的范围继续学;不必从头读完整门课程。
RabbitMQ 官方 Java 教程:任务队列与可靠发布 (新标签页)↗
只做任务队列的手动确认与预取练习,分别记录任务进入、开始处理和完成确认的时刻,区分排队等待与实际处理。
查看学习准备与访问说明 →