摘要
- RFC 9218 用
u=0…7表示响应的紧迫程度,用 Booleani表示分块到达是否能逐步产生价值。初始偏好放在端到端Priority字段里,HTTP/2 与 HTTP/3 的PRIORITY_UPDATE只能更新当前一跳。 - 这些值不是带宽预留、完成顺序或 CPU 优先权。origin、cache、CDN、backend 与 transport 都拥有各自的局部决策;response 中出现
Priority也不等于对方确认执行过优先级。 - 可审计系统要分别保存 client、origin 与每个 intermediary 的原始值、改写和合并规则,并把它们与 queue、flow control、DATA bytes、丢包、重传及用户可见 milestone 对齐,才能判断信号是否真正影响结果。
一个页面里,没有天然的第一名
浏览器打开新闻首页时,先在 <head> 里发现字体,随后解析到响应式英雄图,最后由脚本发出 analytics 请求。字体决定文字何时可读,图片决定最大内容绘制,analytics 对当前交互几乎没有价值。浏览器先提高字体优先级;layout 完成后又发现英雄图已经进入 viewport,于是对仍在传输的图片提高优先级。
源站掌握另一组事实:字体往往在 edge cache 命中,而英雄图需要经过拥塞的 origin shield。CDN 还要考虑共享 backend 上的其他租户。若只听眼前 client 的 u=0,某个页面可以让别人的普通响应长期没有进度。
因此,三个参与者对“什么先有用”都可能判断正确,却没有谁拥有整条路径。瀑布图里图片先完成,可能是 cache hit,而不是优先级生效;字体先完成,也可能是其 bytes 在更新到达前已经进入发送窗口。只看字段和结束时间,无法证明中间发生了哪项调度决定。
u 与 i 描述价值,不分配产权
RFC 9218 以一个 Structured Fields Dictionary 代替旧式 HTTP/2 dependency tree。u 是 0 至 7 的整数,0 最紧急,7 最不紧急;请求没有提供时默认 3。i 是 Boolean,默认 false,描述一个响应的部分内容是否在完整到达前就能被使用。
两个参数解决的不是同一件事。urgency 比较“先后价值”;incremental 比较“分到一点带宽是否已经有用”。两张渐进图片可以分享连接,让用户较早看到两者轮廓;一个压缩包可能只有完整到达才可使用。
规范建议在可能时先发送更紧急的响应。同一 urgency 下,non-incremental 响应可按请求顺序逐个完成,incremental 响应可共享带宽。这里每一步都是 scheduler guidance,不是 entitlement。两个资源都写 u=0 时,协议没有提供唯一冠军;所有资源都标成紧急,只会消灭信号的信息量。
u=7 适合软件更新之类后台流量,却不是无限期饿死它的许可证。严格优先级若让 split backend 上的低优先请求完全不前进,对端可能把沉默当作 connection stall。局部调度器给每条流量最小 quantum,是在保护系统,而不是违反 RFC。
Header 能走到终点,update 只走一跳
请求或响应都可以携带 Priority。它被定义为 end-to-end field,使 client 的初始判断可以穿过 intermediary,也让 origin 的响应判断可以随 cache object 保存。它表达某个 endpoint 的观点,而不表达执行回执。
请求发出后,判断可能改变。原本 u=7 的 prefetch 在用户点击后变为页面关键依赖。HTTP/2 使用 frame type 0x10,HTTP/3 使用 0xF0700 或 0xF0701,把完整 Priority Field Value 关联到 request 或 push element。PRIORITY_UPDATE 是 hop-by-hop:它只告诉直接 peer 当前看法发生变化。
这个区别让 provenance 成为必要数据。CDN 可以保留原始 request header,同时在 backend hop 上发出不同 update;它也可以替换 header,从而改变后续所有节点看到的值。把这些记录压成单一 “effective priority”,会抹去到底是谁提出、谁修改、谁负责的证据。
HTTP/3 的 control stream 还可能先于 target request stream 到达。server 可以暂存最近一次 update,等 stream 打开后应用,但 pending state 会消耗 memory。规范允许本地限制,并用“只留最新值”控制资源。client 有表达权,不拥有对端无限保存更新历史的权力。
Origin 的不同意见不是协议违规
client 未必最了解内容。origin 可能知道某个字体影响所有文本,或一张看似装饰的图片实际承载核心信息,于是返回 response Priority。intermediary 可以把 client 与 server 的参数合并,但 RFC 9218 刻意不规定唯一算法。
请求与响应对“缺失参数”的含义还不同。request 缺少参数意味着使用默认值;response 缺少某个参数意味着 origin 不想更改 client 在该参数上的值。若一套 normalization 对两者同样处理,就会把有效偏好静默清零。
更重要的是,response header 不是 acknowledgement。看到它不能得出“CDN 已按此调度”。也许响应已经从 cache 完成,也许 fairness floor 阻止严格执行,也许 transport flow control 才是瓶颈。监测系统若仅因字段出现就标记 “honored”,是在创造不存在的协议状态。
Connection mapping 决定比较范围
edge 会把多个前端连接 coalesce 到较少 backend,也可能把一个 client 的请求拆到多个 origin connection。于是 urgency 的比较集合随 hop 改变。u=1 只在一个具体 scheduler 的竞争队列中有意义,不是全互联网通用排名。
公平性还依赖身份范围。RFC 9218 指出,HTTP/1.1 backend 若按 client priority 排队,应能把该信息限定到单个 end client;authentication 或 session data 可能提供连接,Priority 本身不能。如果匿名租户共享队列,任意一方靠 u=0 夺取容量,偏好字段便被错误升级成跨租户资源声明。
有些部署会主动制造不公平,例如付费等级获得更多容量,或纯后台更新连接使用 scavenging congestion controller。这可以是明确的商业或运营决策,但必须公开 owner、度量与边界。不能把本地选择伪装成 wire value 强制要求。
最后一票仍在 transport 手里
HTTP scheduler 之后还有 TCP 或 QUIC。congestion control、flow-control window、丢包与重传都会重排实际发送机会。cache hit 可以轻易超过高优先的 miss;backend computation 可能在响应进入 byte scheduler 前就耗掉时间。
HTTP/3 面对丢包时,可以在“低 urgency stream 的重传”和“高 urgency stream 的新数据”之间选择。RFC 9218 没有给出通用答案,因为 recovery 与应用价值的权衡只能由运行实现掌握。header 无法替代该实现内部的证据。
所以,完成顺序只是 client 观察,不是因果证明。调查至少要关联 connection/stream ID、原始 header 与所有 update、同队列竞争者、scheduler 版本与 quantum、flow control、congestion、每个 interval 的 DATA bytes、loss/retransmission、cache/backend 时间和目标用户指标。
Registry、library 与运行结果是三项证据
IANA 注册 u、i、HTTP/2 setting 0x9、frame 0x10 和 HTTP/3 frame values,解决的是号码与语法冲突。它不证明某个生产 peer 协商、解析、启用或执行了这些机制。
nghttp2 的文档把落差写得很清楚:application 要声明停止旧 RFC 7540 signals,配置接收 extension frame,通过 request API 发送 header,或调用专用函数发送 update。library 具备接口只是第一步;配置、application handler、scheduler 连接和实际 bytes 都需单独证明。
可靠的 “支持 RFC 9218” 应拆成六项:negotiation、精确 parsing、provenance 与 merge、queue state、byte allocation、受控 contention 下的用户结果。缺一项,结论就只能停在 capability claim。
薄规范拒绝替本地系统夺权
RFC 9218 最接近 Heng Lu 所说的 Minimum Initial Specification:两个核心参数、一个共享字典、一个端到端字段和各版本更新帧。它没有发明全球统一 scheduler,也没有替每个 operator 决定 fairness、backend mapping、cache 或 retransmission。
Localized Future Decision 允许不同实现根据资源、客户和链路作不同选择,但这些选择必须可观察。Voluntary Adoption 要由真实协商与 canary 行为证明,而不是 RFC 编号或 registry 行。Running-Code Primacy 则要求把 A 的声明、B 的改写、C 的规则、D 的 bytes 和 E 的结果连成可复查链。
没有这条链,“urgent” 只是线上一个词,不拥有下一个 byte。
资料来源
- RFC 9218 — Extensible Prioritization Scheme for HTTP
- RFC 9113 — HTTP/2
- RFC 9114 — HTTP/3
- RFC 8941 — Structured Field Values for HTTP
- RFC 9111 — HTTP Caching
- IANA — HTTP Priority
- IANA — HTTP/2 Parameters
- IANA — HTTP/3 Parameters
- nghttp2 Programmer's Guide — Stream priorities
- nghttp2 —
nghttp2_submit_priority_update - Heng Lu — Running-Code Primacy
- Heng Lu — Minimum Initial Specification
会员简报
档案背景详情
使用相应会员等级登录,即可解锁完整简报与来源注释。
仅限 Strategic Circle
Strategic Circle
所有读者均可浏览。加入并登录后可解锁档案简报。
加入 Strategic Circle仅限 Leadership Alliance
Leadership Alliance
符合条件的 IP 资产所有者和管理层可登录查看 Leadership Alliance 简报。
加入 Leadership Alliance
