IIS 上的 HTTP/2
作者:David So
兼容性
版本 | 说明 |
---|---|
IIS 10.0 | IIS 10.0 中引入了对 HTTP/2 的支持 |
IIS 8.5 和更低版本 | IIS 10.0 之前的版本不支持 HTTP/2 |
什么是 HTTP/2?
HTTP/2 是对 HTTP 语义如何在 TCP 连接上流动的重新设计,而且 Windows 10 和 Windows Server 2016 中提供了对 HTTP/2 的支持。 HTTP/2 是在 HTTP/1.1 使用近 20 年后的重大升级,可降低延迟和连接负载对 Web 服务器的影响。
HTTP/1.1 的主要进步是使用持久连接来连续服务多个请求。 在 HTTP/2 中,持久连接可用于为多个同时请求提供服务。 在此过程中,HTTP/2 引入了一些其他功能,可提高 HTTP 在网络上的效率。
一个连接处理多个请求
每个 TCP 连接都需要往返才能设置。 如果使用加密,TLS 握手会执行另外 1-2 次往返。 所有这一切都发生在可以发送第一个响应的第一个字节之前。 通过重用现有连接而不是设置新连接,这一开销可以由多个请求分担。 HTTP/2 可大幅减少请求在建立新连接时等待或等待现有连接变为空闲的需求。 由于单个连接是在多个请求之间多路复用的,因此请求通常可以立即发送,而无需等待其他请求完成。
使用 HPACK 进行标头压缩
HTTP 长期以来一直支持数据压缩。 但是,标头却是以未压缩的文本形式发送的,请求之间存在大量冗余。 (许多最长的标头在每个请求中都使用完全相同的值发送!)HTTP/2 引入了 HPACK,这是一种 HTTP 标头压缩方案,可减少请求之间的冗余。
压缩有助于多路复用,因为请求更小。 这使得客户端能够在连接上的第一个数据包中发出多个请求,而 TCP 流控制窗口仍然很小。
服务器推送
请求是有一定模式的。 如果客户端请求一个资源,服务器通常会预测它需要页面上引用的其他资源。 在 HTTP/1.1 中,内联用于将这些资源作为第一个响应的一部分传递到客户端。 内联有其缺点,最明显的是,内联资源无法缓存以供在也可能引用它的其他页面上使用。
HTTP/2 引入了“推送”的概念,即服务器将响应客户端尚未发出但预测其会发出的请求。 这样,服务器就可以继续提供内联的延迟优势,但采用的是客户端可以在其他页面上缓存和重用的形式。
如何使用 HTTP/2?
你可能已经在使用了! 因为几乎所有浏览器在其最新版本中都已支持 HTTP/2,并且当前数据显示,超过 50% 的用户已在使用支持 HTTP/2 的浏览器。
在服务器上,在 Windows 10 或 Windows Server 2016 上运行的 IIS 支持 HTTP/2。
IIS 当前仅通过 TLS 支持 HTTP/2。 对于在 Windows 10 上运行 IIS 的 Web 服务器,当与其建立 HTTPS 连接时,如果客户端和服务器都支持 HTTP/2,则会使用 HTTP/2。 在 IIS 中,我们尽可能透明地实现了 HTTP/2,这意味着你无需更改应用程序中的任何内容即可运行 HTTP/2。 不过,HTTP/2 中不再建议使用某些 HTTP/1.1 优化(域分片、内联等),因此你应该计划在未来删除这些优化。
推送方面呢?
由于服务器推送是 HTTP/2 中的一项新功能,因此需要调用新的 API 来利用它。 当调用 ASP.NET 中的 PushPromise API 或从 IIS 本机模块调用 HttpDeclarePush API 时,将为预期客户端将要发出的请求提供 URL 和可选请求头。 如果基础连接支持推送,则会发生两种情况:
- PUSH_PROMISE 将发送到客户端,因此客户端可以检查缓存中是否已存在资源
- 新的请求将添加到已推送资源的请求队列中
如果基础连接不支持推送(客户端禁用推送或为 HTTP/1.1 客户端),则调用不执行任何操作并返回成功,因此可以安全地调用 API,而无需担心是否允许推送。
IIS 设置
没有特定于 HTTP/2 的新 IIS 配置设置。
在 Windows Server 2016 技术预览中,提到了设置“DuoEnabled”注册表项。 此信息不再是必需的。 如上所述,如果客户端和服务器配置支持 HTTP/2,则 IIS 将使用 HTTP/2(如果不可能,则回退到 HTTP/1.1)。
日志记录协议版本
IIS 日志记录有一个“协议版本”字段,默认情况下处于关闭状态。 如果要跟踪哪些请求将通过 HTTP/2、HTTP/1.1 等发送,则启用此字段非常有用。
在 Internet 服务管理器 UI 中,可以在“日志记录”功能下通过“选择字段”找到此功能。
进行更改后,单击最右侧的“操作”窗格下的“应用”。
下面是启用了“协议版本”字段的示例日志文件输出:
#Software: Microsoft Internet Information Services 10.0
#Version: 1.0
#Date: 2015-08-13 18:46:11
#Fields: date time s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs-version cs(User-Agent) cs(Referer) sc-status sc-substatus sc-win32-status time-taken
2015-08-13 18:46:11 ::1 GET / - 443 - ::1 HTTP/2.0 Mozilla/5.0+(Windows+NT+10.0;+WOW64;+Trident/7.0;+Touch;+rv:11.0)+like+Gecko - 200 0 0 391
2015-08-13 18:46:11 ::1 GET /iisstart.png - 443 - ::1 HTTP/2.0 Mozilla/5.0+(Windows+NT+10.0;+WOW64;+Trident/7.0;+Touch;+rv:11.0)+like+Gecko https://localhost/ 200 0 0 100
在 IIS 中使用 HTTP/2 的演示演练
如果运行的是 Windows 10,可通过依次访问“程序和功能”和“启用或关闭 Windows 功能”,然后启用“Internet Information Services”复选框找到此功能。 如果运行的是 Windows Server 2016,则启动“服务器管理器”,然后在仪表板上启用“添加角色和功能”,然后从列表中选择“Web 服务器”(IIS)。
安装完成后,启动 Internet 服务管理器并创建自签名证书,方法是在服务器的“功能”视图下选择“服务器证书”选项。 请注意,此示例中的自签名证书仅用于演示/测试目的(不建议用于保护生产站点)。
转到默认网站,然后在“绑定”下,使用刚创建的自签名证书创建新的 TLS 绑定。
从 Windows 10 或 Windows Server 2016 计算机启动浏览器并点击 F12(或转到“设置”并启用“F12 开发人员工具”),然后切换到“网络”选项卡。浏览到
https://localhost
,瞧,你正在使用 HTTP/2!
在什么情况下 HTTP/2 不受支持?
在少数情况下,HTTP/2 不能与其他功能配合使用。 在这些情况下,Windows 将回退到 HTTP/1.1 并继续执行事务。 这可能涉及在握手期间协商 HTTP/1.1,或向客户端发送错误代码,指示其通过 HTTP/1.1 连接重试。
- HTTP/2 不支持 Windows 身份验证(NTLM/Kerberos/协商)。 在这种情况下,IIS 将回退到 HTTP/1.1。
- 明文 - 如上所述,IIS 目前仅支持基于 TLS 的 HTTP/2。 同样,IIS 将回退到 HTTP/1.1。
- 带宽限制 - IIS 具有限制带宽的功能(在 Inetmgr 中,选择站点,在“操作”窗格的“配置”下选择“限制”)。 这适用于 HTTP/1.1,但未在 HTTP/2 上强制实施(执行期间不会出现错误或带宽限制)。
详细信息
有关 HTTP/2 和 Windows 中的客户端和服务器实现的更深入的讨论,请参阅 Windows 10 中的 Build 2015 HTTP/2 讨论:浏览器、应用和 Web 服务器。
作者:Mike Bishop、David So(参与者包括 Rob Trace、Baris Caglar 和 Nazim Lala,并向其表示感谢)