对 ASP.NET Core Kestrel Web 服务器使用 HTTP/3

HTTP/3 是建议的标准,也是 HTTP 的第三个主要版本。 本文介绍 HTTP/3 的要求。 ASP.NET Core 7.0 及更高版本完全支持 HTTP/3。

重要

配置为利用 HTTP/3 的应用应设计为也支持 HTTP/1.1 和 HTTP/2。

HTTP/3 要求

HTTP/3 的要求因操作系统而异。 如果 Kestrel 所运行的平台没有满足 HTTP/3 的所有要求,则它会被禁用,而 Kestrel 将回退到其他 HTTP 协议。

Windows

  • Windows 11 版本 22000 或更高版本/Windows Server 2022。
  • TLS 1.3 或更高版本的连接。

Linux

  • 已安装 libmsquic 包。

libmsquic 是通过位于 packages.microsoft.com 的 Microsoft 官方 Linux 包存储库发布的。 若要安装此包,请执行以下操作:

  1. 添加 packages.microsoft.com 存储库。 有关说明,请参阅 Microsoft 产品的 Linux 软件存储库
  2. 使用发行版的包管理器安装 libmsquic 包。 例如,在 Ubuntu 上为 apt install libmsquic=1.9*

注意:.NET 6 仅与 libmsquic 的 1.9.x 版本兼容。 由于中断性变更,Libmsquic 2.x 不兼容。 如果需要,Libmsquic 会接收对 1.9.x 的更新,以合并安全修补程序。

macOS

HTTP/3 目前在 macOS 上不受支持,它可能在未来版本中可用。

入门

默认情况下,不启用 HTTP/3。 将配置添加到 Program.cs 以启用 HTTP/3。

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, options) =>
{
    options.ListenAnyIP(5001, listenOptions =>
    {
        listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3;
        listenOptions.UseHttps();
    });
});

上述代码将端口 5001 配置为:

  • 通过指定 HttpProtocols.Http1AndHttp2AndHttp3,将 HTTP/3 与 HTTP/1.1 和 HTTP/2 一起使用。
  • 使用 UseHttps 启用 HTTPS。 HTTP/3 需要 HTTPS。

由于并非所有路由器、防火墙和代理都能正确地支持 HTTP/3,因此 HTTP/3 应与 HTTP/1.1 和 HTTP/2 一起配置。 可通过将 HttpProtocols.Http1AndHttp2AndHttp3 指定为终结点支持的协议来完成此操作。

有关详细信息,请参阅为 ASP.NET Core Web 服务器配置终结点。

Alt-svc

HTTP/3 是通过 alt-svc 标头作为从 HTTP/1.1 或 HTTP/2 的升级发现的。 这意味着,在切换到 HTTP/3 之前,第一个请求通常使用 HTTP/1.1 或 HTTP/2。 如果启用了 HTTP/3,则 Kestrel 会自动添加 alt-svc 标头。

Localhost 测试

HTTP/3 的好处

HTTP/3 使用与 HTTP/1.1 和 HTTP/2 相同的语义:相同的请求方法、状态代码和消息字段适用于所有版本。 差异在于基础传输。 HTTP/1.1 和 HTTP/2 都将 TCP 用作其传输协议。 HTTP/3 使用的是与 HTTP/3 同时开发的一种新传输技术,称为 QUIC

与 HTTP/1.1 和 HTTP/2 相比,HTTP/3 和 QUIC 具有很多优势:

  • 第一个请求的响应时间更短。 QUIC 和 HTTP/3 在客户端和服务器之间以较少的往返次数协商连接。 第一个请求会更快地到达服务器。
  • 改进了发生连接数据包丢失时的体验。 HTTP/2 通过一个 TCP 连接多路复用多个请求。 如果在连接时发生数据包丢失,会影响所有请求。 这个问题称为“队头阻塞”。 由于 QUIC 提供本机多路复用,因此丢失的数据包只会影响已丢失数据的请求。
  • 支持在网络之间转换。 此功能对于移动设备非常有用,因为在移动设备更改位置时,在 WIFI 和移动电话网络之间切换是很常见的。 目前,在切换网络时,HTTP/1.1 和 HTTP/2 连接会失败并提示错误。 应用或 Web 浏览器必须重试任何失败的 HTTP 请求。 HTTP/3 让应用或 Web 浏览器在网络发生更改时可以无缝地继续。 Kestrel 不支持 .NET 6 中的网络转换。 它可能在未来版本中可用。

HTTP/3 是 HTTP 的第三个即将发布的主要版本。 本文介绍 HTTP/3 的要求以及如何配置 Kestrel 才能使用它。

重要

HTTP/3 在 .NET 6 中作为预览功能提供。 HTTP/3 规范还没有最终确定,并且对于 .NET 6,HTTP/3 可能存在行为或性能问题。

有关预览功能支持的详细信息,请参阅支持的预览功能部分

配置为利用 HTTP/3 的应用应设计为也支持 HTTP/1.1 和 HTTP/2。 如果在 HTTP/3 中标识了问题,建议禁用 HTTP/3,直到问题在 ASP.NET Core 的未来版本中得到解决。 “公告”GitHub 存储库中报告了重要问题。

HTTP/3 要求

HTTP/3 的要求因操作系统而异。 如果 Kestrel 所运行的平台没有满足 HTTP/3 的所有要求,则它会被禁用,而 Kestrel 将回退到其他 HTTP 协议。

Windows

  • Windows 11 版本 22000 或更高版本/Windows Server 2022。
  • TLS 1.3 或更高版本的连接。

Linux

  • 已安装 libmsquic 包。

libmsquic 是通过位于 packages.microsoft.com 的 Microsoft 官方 Linux 包存储库发布的。 若要安装此包,请执行以下操作:

  1. 添加 packages.microsoft.com 存储库。 有关说明,请参阅 Microsoft 产品的 Linux 软件存储库
  2. 使用发行版的包管理器安装 libmsquic 包。 例如,在 Ubuntu 上为 apt install libmsquic=1.9*

注意:.NET 6 仅与 libmsquic 的 1.9.x 版本兼容。 由于中断性变更,Libmsquic 2.x 不兼容。 如果需要,Libmsquic 会接收对 1.9.x 的更新,以合并安全修补程序。

macOS

HTTP/3 目前在 macOS 上不受支持,它可能在未来版本中可用。

入门

默认情况下,不启用 HTTP/3。 将配置添加到 Program.cs 以启用 HTTP/3。

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, options) =>
{
    options.ListenAnyIP(5001, listenOptions =>
    {
        listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3;
        listenOptions.UseHttps();
    });
});

上述代码将端口 5001 配置为:

  • 通过指定 HttpProtocols.Http1AndHttp2AndHttp3,将 HTTP/3 与 HTTP/1.1 和 HTTP/2 一起使用。
  • 使用 UseHttps 启用 HTTPS。 HTTP/3 需要 HTTPS。

由于并非所有路由器、防火墙和代理都能正确地支持 HTTP/3,因此 HTTP/3 应与 HTTP/1.1 和 HTTP/2 一起配置。 可通过将 HttpProtocols.Http1AndHttp2AndHttp3 指定为终结点支持的协议来完成此操作。

有关详细信息,请参阅为 ASP.NET Core Web 服务器配置终结点。

Alt-svc

HTTP/3 是通过 alt-svc 标头作为从 HTTP/1.1 或 HTTP/2 的升级发现的。 这意味着,在切换到 HTTP/3 之前,第一个请求通常使用 HTTP/1.1 或 HTTP/2。 如果启用了 HTTP/3,则 Kestrel 会自动添加 alt-svc 标头。

Localhost 测试

  • 浏览器不允许在 HTTP/3 上使用自签名证书,例如 Kestrel 开发证书。

  • HttpClient 可用于 .NET 6 或更高版本中的 localhost/loopback 测试。 使用 HttpClient 进行 HTTP/3 请求时,需要额外的配置:

    • HttpRequestMessage.Version 设置为 3.0,或者
    • HttpRequestMessage.VersionPolicy 设置为 HttpVersionPolicy.RequestVersionOrHigher

限制

Kestrel 中的 HTTP/3 尚不支持某些 HTTPS 方案。 使用 HTTP/3 时,如果通过 HttpsConnectionAdapterOptions 调用 Microsoft.AspNetCore.Hosting.ListenOptionsHttpsExtensions.UseHttps,则在 HttpsConnectionAdapterOptions 上设置以下选项是一个 no-op(不执行任何操作):

使用 HTTP/3 时,调用 Microsoft.AspNetCore.Hosting.ListenOptionsHttpsExtensions.UseHttps 的以下实现会引发错误:

HTTP/3 的好处

HTTP/3 使用与 HTTP/1.1 和 HTTP/2 相同的语义:相同的请求方法、状态代码和消息字段适用于所有版本。 差异在于基础传输。 HTTP/1.1 和 HTTP/2 都将 TCP 用作其传输协议。 HTTP/3 使用的是与 HTTP/3 同时开发的一种新传输技术,称为 QUIC

与 HTTP/1.1 和 HTTP/2 相比,HTTP/3 和 QUIC 具有很多优势:

  • 第一个请求的响应时间更短。 QUIC 和 HTTP/3 在客户端和服务器之间以较少的往返次数协商连接。 第一个请求会更快地到达服务器。
  • 改进了发生连接数据包丢失时的体验。 HTTP/2 通过一个 TCP 连接多路复用多个请求。 如果在连接时发生数据包丢失,会影响所有请求。 这个问题称为“队头阻塞”。 由于 QUIC 提供本机多路复用,因此丢失的数据包只会影响已丢失数据的请求。
  • 支持在网络之间转换。 此功能对于移动设备非常有用,因为在移动设备更改位置时,在 WIFI 和移动电话网络之间切换是很常见的。 目前,在切换网络时,HTTP/1.1 和 HTTP/2 连接会失败并提示错误。 应用或 Web 浏览器必须重试任何失败的 HTTP 请求。 HTTP/3 让应用或 Web 浏览器在网络发生更改时可以无缝地继续。 Kestrel 不支持 .NET 6 中的网络转换。 它可能在未来版本中可用。