一次突发就撑满队列:从负载包络推到 admission¶
平均 1000 requests/s,设备能完成 2000 requests/s,为什么系统仍会满队列?平均服务能力高于平均到达,只解释长期趋势,没有描述短时突发、暂停和结果交付。
资源预算已计算固定结构与历史 4 / 16 额度。本章继续讨论怎样把负载、服务和时限推成容量与接受规则。下文数值是设计推导,不是公开 SDK 的新测试结果。
用业务负载描述输入¶
容量设计至少需要以下输入:
| 输入 | 示例问题 | 影响 |
|---|---|---|
| 到达包络 | 任意 20 ms 内最多多少请求? | 突发与入口容量 |
| payload 与数据流 | 控制消息小,数据帧是否持续到达? | 字节容量、复制与带宽 |
| 服务行为 | 串行、并行,还是提交后等待? | 有效并发与完成速率 |
| 暂停 | reset、回收、调度或断连最长多久? | 累积积压与拒绝窗口 |
| 完成定义 | 设备完成还是业务已收到结果? | 交付与 callback 成本 |
| SLO | 时延、失败、丢弃与恢复容忍度? | admission、降级与故障终态 |
只给平均 requests/s,无法选择可靠的队列深度。只有最大 payload,也无法判断持续流的字节预算。需要记录典型、峰值、持续时间和不可接受的结果。
把突发写成一个简单包络¶
先分析一个不拒绝、不丢弃的参考系统,以判断完整负载需要多少资源。采用可解释的近似:任意长度为 t 的时间窗口,最多到达 b + r×t 个请求;b 是允许的突发量,r 是持续到达率。
再假设任意持续有积压的服务区间,都满足一个速率—时延服务下界:至多 T 的延迟之后,至少按速率 R 提供服务。T 不只是一次观察到的暂停,R 也不能只用平均吞吐代替。忽略离散取整与其它流水线阶段时:
这是单个到达包络与速率—时延服务曲线的基本推导,背景见 Le Boudec / Thiran 的 Network Calculus。这些边界只有在包络和服务下界成立、单位一致、FIFO 等假设明确时才有意义。有限历史 p99 不能提供恒定 R 或最长 T 的证明;实际部署中还应考虑离散消息、并发限制、复制、交付和安全余量。
用规划算例:b=40,r=1000/s,T=10ms,R=2000/s。积压上界为 50 个请求,时延上界为 30 ms。仅凭上界高于 10 ms,不能断言每次实际运行都会越界;但该模型确实允许如下反例:开始时突发 40 笔,服务暂停 10 ms 后按 2000/s 执行,初始突发的最后一笔约在 30 ms 才完成。暂停期间继续到达的 10 笔还会让峰值积压达到 50。若需求是对所有允许输入保证 10 ms,单纯加深队列不会让这项设计通过;需要限制突发、缩短暂停、增加有效服务,或明确拒绝策略。
入口容量和 accepted 容量分开核算¶
公开 SDK 的 ingress 上限是 64,accepted 请求槽的物理上限是 16。两者的状态与结果义务不同:
64 个入口项不能当作 64 个已接受请求,16 个 accepted 槽也不能覆盖全部 API 已返回 QUEUED 的 ticket。还要分别核算输出报文、后端、数据队列及业务消费者。
每个队列写清五项:存什么、容量单位、达到上限的行为、上游看见什么、停止时怎样结算。字节预算与条数预算同时使用,避免大 payload 使固定条数变成不可控内存。
固定结构账已经包含数组时,不再把每层分解项重复加到总数;backend 进程和内核资源也不因为不在 sizeof(runtime) 中就消失。
Little 定律用于检查平均关系¶
在稳定系统、相同边界与单位下,平均在途量、平均到达率和平均停留时间满足:
平均值关系及其统计边界可参考 MIT 排队系统课程讲义。
例如同一条完成路径上,平均 1000 requests/s、平均停留 6 ms,对应平均约 6 个在途请求。它有助于检查测量是否自洽,却不告诉最大队列要多深,也不保证 p99 或最坏停止时间。
历史额度基准是闭环窗口,producer 根据完成节奏继续提交。用吞吐和时延推导时,不能把这个受控到达过程替换成持续外部业务。测量边界见 尾延迟诊断。
deadline 应不应该参与接受判断¶
一个请求还剩 2 ms,但已知前面有 20 笔串行工作,每笔至少占用 1 ms。将它接受到队列里,随后再超时,可能同时浪费容量和设备工作。
如果存在可信的服务边界,可以把“是否有机会按期交付”纳入 admission:
满足这个式子仍不等于所有故障都不会发生。服务估计必须记录来源与失效条件;没有可靠界限时,应该表达为尽力服务,不能据启发式估计承诺硬时限。
当前 SDK 的 ACCEPT 主要受状态、额度和契约约束,没有实现完整的基于服务预算的 admission。为它增加这项策略,需要新增拒绝原因、统计和边界测试,同时核对两端 runtime 的共同语义。
拒绝、丢弃与降级不是同一种结果¶
| 工作类型 | 常见候选 | 要保留的契约 |
|---|---|---|
| 控制请求 | 明确拒绝新工作 | 调用者知道未接受,不等待不存在的结果 |
| 状态更新 | 合并为最新值 | 哪些中间状态可跳过,序号怎样解释 |
| 数据流 | 丢旧 / 丢新 / 降采样 | 丢弃计数、序列缺口与质量影响 |
| 重要事务 | 有限持久队列或上游协调 | 重启后的身份、去重和存储失败 |
重试不是免费的上游反应。拒绝后立即重试会增大到达率,各层各重试一次还会放大同一业务意图。应由明确的一层拥有重试预算、截止时间和退避,细节见 故障与恢复。
控制与数据可以分队列、分额度和分调度预算,但共享 owner、设备或资源组时仍会争用。架构图应标出这些共享点。
有限容量还要能安全关闭¶
停止关闭新到达后,已有工作量才成为有限集合。若通知成本有界,可以推导交付成本;若 callback 无限阻塞,再小的队列也不能保证有限退出。
容量评审同时记录正常峰值、故障期积压、恢复新旧代际共存,以及停止剩余义务。对一份旧会话超时后还可能执行的设备请求,不能仅从本地 live=0 推断设备已经静止。
Linux 停止案例验证 queued / accepted / terminal 的本地守恒;远端副作用与硬件停止由对应协议和设备责任承担。
一份可以执行的决策记录¶
本章算例的结论是:在给定包络和服务假设下,10 ms 时限不成立,扩大队列不是解决办法。下一步候选及证据如下:
| 候选 | 改变哪项输入 | 需要证明什么 |
|---|---|---|
| 限制 b | 收紧突发接受 | 上游接受拒绝 / 降级,业务仍有效 |
| 缩短 T | 减少公共暂停 | 调度、回调、恢复与回收的停顿边界 |
| 增加 R | 提升有效服务 | 后端可以并行,交付不成为新瓶颈 |
| 调整 SLO | 改变业务承诺 | 更长等待在业务上可接受 |
对照实验记录实际到达、服务、各队列峰值、终态、时延及停止。若实测不满足服务下界,撤回边界保证并重新建模。这比直接选择一个“足够大”的队列更能说明平台决定的依据。