Skip to main content

2. Motivation for Replacing RFC 7540 Stream Priorities (替换 RFC 7540 流优先级的动机)

RFC 7540 流优先级(参见 [RFC7540] 的第 5.3 节)是一个复杂的系统,其中客户端发送流依赖关系和权重信号以描述一个不平衡树。它遭受了有限的部署和互操作性问题,并已在 HTTP/2 [HTTP/2] 的修订版中被弃用。HTTP/2 保留这些协议元素以维护线路兼容性(参见 [HTTP/2] 的第 5.3.2 节),这意味着即使存在替代信号(例如本文档描述的方案),它们仍可能被使用。

许多 RFC 7540 服务器实现不会对 HTTP/2 优先级信号采取行动。

优先级排序可以使用服务器拥有的关于资源或生成请求的顺序的信息。例如,了解 HTML 文档结构的服务器可能希望优先交付对用户体验至关重要的图像,而不是其他图像。使用 RFC 7540,服务器很难解释来自客户端的优先级排序信号,因为相同的条件可能导致不同客户端发出非常不同的信号。本文档描述的信号更简单且更受约束,需要更少的解释并允许更少的变化。

RFC 7540 没有定义服务器可以用来向中介提供优先级信号的方法。

RFC 7540 流优先级是相对于同时共享同一连接的其他请求表达的。将这样的设计纳入在不了解其他请求如何共享连接的情况下生成请求的应用程序,或纳入在流之间没有强排序保证的协议(如 HTTP/3 [HTTP/3])中是困难的。

来自独立研究 [MARX] 的实验表明,至少对于 Web 用例,更简单的方案可以达到与实践中看到的更复杂的 RFC 7540 设置相当的性能特征。

2.1. Disabling RFC 7540 Stream Priorities (禁用 RFC 7540 流优先级)

上述问题和见解为 RFC 7540 流优先级的替代方案(参见 [HTTP/2] 的第 5.3 节)提供了动机。

本文档定义了 SETTINGS_NO_RFC7540_PRIORITIES HTTP/2 设置,以允许端点省略或忽略 HTTP/2 优先级信号(参见 [HTTP/2] 的第 5.3.2 节),如下所述。SETTINGS_NO_RFC7540_PRIORITIES 的值必须 (MUST) 为 0 或 1。除 0 或 1 之外的任何值必须 (MUST) 被视为类型为 PROTOCOL_ERROR 的连接错误(参见 [HTTP/2] 的第 5.4.1 节)。初始值为 0。

如果端点使用 SETTINGS_NO_RFC7540_PRIORITIES,它们必须 (MUST) 在第一个 SETTINGS 帧中发送它。发送方在第一个 SETTINGS 帧之后禁止 (MUST NOT) 更改 SETTINGS_NO_RFC7540_PRIORITIES 值。检测到更改的接收方可以 (MAY) 将其视为类型为 PROTOCOL_ERROR 的连接错误。

客户端可以发送值为 1 的 SETTINGS_NO_RFC7540_PRIORITIES 以表示它们不使用 HTTP/2 优先级信号。SETTINGS 帧在来自客户端的任何 HTTP/2 优先级信号之前,因此服务器可以在信号到达之前确定是否需要为信号处理分配任何资源。接收到值为 1 的 SETTINGS_NO_RFC7540_PRIORITIES 的服务器必须 (MUST) 忽略 HTTP/2 优先级信号。

服务器可以发送值为 1 的 SETTINGS_NO_RFC7540_PRIORITIES 以表示它们将忽略客户端发送的 HTTP/2 优先级信号。

发送 SETTINGS_NO_RFC7540_PRIORITIES 的端点被鼓励使用替代优先级信号(例如,参见第 5 节或第 7.1 节),但没有使用特定信号类型的要求。

2.1.1. Advice when Using Extensible Priorities as the Alternative (使用可扩展优先级作为替代方案时的建议)

在从服务器接收 SETTINGS 帧之前,客户端不知道服务器是否忽略 HTTP/2 优先级信号。因此,在客户端从服务器接收 SETTINGS 帧之前,客户端应该 (SHOULD) 同时发送 HTTP/2 优先级信号和本优先级方案的信号(参见第 5 节和第 7.1 节)。

一旦客户端接收到包含值为 1 的 SETTINGS_NO_RFC7540_PRIORITIES 参数的第一个 SETTINGS 帧,它应该 (SHOULD) 停止发送 HTTP/2 优先级信号。这避免了发送已知会被忽略的冗余信号。

类似地,如果客户端接收到值为 0 的 SETTINGS_NO_RFC7540_PRIORITIES 或设置参数不存在,它应该 (SHOULD) 停止发送 PRIORITY_UPDATE 帧(第 7.1 节),因为这些帧可能会被忽略。但是,客户端可以 (MAY) 继续发送 Priority 头字段(第 5 节),因为它是端到端信号,可能对客户端直接连接的服务器后面的节点有用。