HTTP(Hypertext Transfer Protocol)超文本传输协议是万维网中应用最广泛的应用层传输协议。HTTP起源于80年代末,最初构想是一个基于单行文本的的协议,第一个协议版本是HTTP/0.9,其第一个全功能迭代(1.0版)于1996年被记录在RFC 1945中。
随着互联网的使用和期望的增长,HTTP协议也需要改进。1.1版于1997年被记录在RFC 2068和1999年的RFC 2616中,随后的RFC(7230-7235)于2014年被记录下来——整整十年半之后!——记录消息语法/路由;语义/内容;条件和范围请求;缓存;和身份验证。
HTTP/2基于Google的SPDY项目,是该协议的第一次重大修改,于2015年在RFC 7540中标准化,同年RFC 7541引入了报头压缩(HPACK)。
HTTP/2推出仅四年后,一个基于谷歌实验性QUIC协议的新标准开始出现:HTTP/3。其目的:提高用户与网站和API交互的速度和安全性。HTTP/3于2022年6月份正式发布第一个官宣版本RFC 9114,这意味着HTTP/3已经标准化了,ASP.NET Core 7.0 已经支持HTTP/3 且 ASP.NET Core 8.0 Preview 1中已经默认启用HTTP/3了!
HTTP/3已经标准化了,那么有人会问HTTP/3是不是会替换HTTP/2?本文描述并比较了协议的两个版本,并给出了各自在何处找到合适应用程序的一些建议。
HTTP protocol stack transition and comparison
Comparo of HTTP protocol stack changes from HTTP/1.1 to HTTP/3

HTTP/2的背景

HTTP/2的创建目的是为了解决HTTP/1.1的非结构化发展所带来的许多问题,其中大部分与性能有关。
HTTP/1.1的问题
  1. HTTP HOL(head of line) 阻塞问题
  2. 未实现多路请求复用的请求流水线
  3. 开启多个TCP连接请求多个资源
  4. 数据传输的文本性质
  5. 长HTTP标头
  6. 克服上述问题引进的解决方案(如域分片,Spriting(sprite maps)等)带来的兼容性和互操作问题
  7. 网页加载速度慢
这些问题很多都是协议本身的限制造成的,归结为响应时间随着流量的增加而增加。
2009 年,Google 宣布了SPDY,一种实验性协议,作为解决 HTTP/1.x 问题的结构化方法。HTTP 工作组注意到 Google 在使用 SPDY 实现更高的性能目标方面取得的成功。2012 年 11 月,以 SPDY 规范为起点,发起了 HTTP/2 提案征集活动RFC 7540

对HTTP/3的诉求

多年来,HTTP 一直在不断发展,从 5 年的 0.9 版,一年的 1.0 版,到大约 15 年的 1.1 版,最终在 2014 年到达第 2 版。在每次迭代中,都会添加新功能满足多种需求的协议,例如应用层要求、安全考虑、会话处理和媒体类型
在这个演变过程中,HTTP 的底层传输机制大体上保持不变。然而,随着公众大量采用移动设备技术,互联网流量呈爆炸式增长,新开箱的 HTTP/2 一直难以提供流畅、透明的 Web 浏览体验。它承受着现代互联网流量的数量和速度,尤其是在实时应用程序及其用户不断增长的需求下。这导致在使用此版本的协议时出现许多警告,暴露出明显的改进机会。

多路复用、负载峰值和请求优先级

Lucidchart 在其负载均衡器(LB)上启用 HTTP/2 后遇到了意想不到的问题

服务器推送变得复杂

如果不小心使用,HTTP/2 推送功能弊大于利。例如,回访者可能有文件的缓存副本,在这种情况下,服务器不应推送资源。使推送缓存感知可以解决这个问题,但这有其自身的注意事项并且很快就会变得复杂。

TCP对头阻塞

HTTP/2 解决了 HTTP 级别的线头阻塞问题,它允许资源被多路发送,同时通过同一连接分解成块。然而,当数据包丢失并且必须以正确的顺序重新发送时,TCP 级别 的线头阻塞仍然会发生

HTTP/2 和 HTTP/3的不同

HTTP/3 的目标是通过解决 HTTP/2 的传输相关问题,在所有形式的设备上提供快速、可靠和安全的 Web 连接。为此,HTTP/3基于谷歌开发的QUIC协议。
HTTP/2 和 HTTP/3 之间的根本区别在于 HTTP/3 运行在 QUIC 上,而 QUIC 运行在无连接的 UDP 上而不是面向连接的 TCP(所有以前版本的 HTTP 都使用)。
Comparison of connection-oriented TCP vs. connectionless UDP, as used in QUIC
在语法和语义结构方面,HTTP/3 与 HTTP/2 类似。HTTP/3 参与相同类型的请求/响应消息交换,其数据格式包含方法、标头、状态代码和正文。但是,HTTP/3 引入的显着差异在于 UDP 之上协议层的堆叠顺序,如下图所示。
Stacking order in HTTP/3 showing QUIC encompassing the security layer and part of the transport layer
下表比较了 HTTP/2 和 HTTP/3 的特性和功能:
Comparison table of features and capabilities of HTTP/2 and HTTP/3 Part 1/2
Comparison table of features and capabilities of HTTP/2 and HTTP/3 Part 2/2
 

HTTP/2 概述

HTTP/2 是 HTTP/1.1 的扩展,而不是它的替代品。应用程序语义保持不变,具有相同的 HTTP 方法、状态代码、URI 和标头字段。
每个 HTTP/2 连接都以 HTTP/1.1 开始,如果客户端支持 HTTP/2,则连接会升级。HTTP/2 在客户端和服务器之间使用单个 TCP 连接,该连接在交互期间保持打开状态。
Requests and responses between a client and a server over TCP, the transport protocol underlying HTTP/2
HTTP/2 引入了许多旨在提高性能的功能:
  • 创建交错通信流的二进制框架层。
  • 完全多路复用而不是强制排序并因此阻塞(这意味着它可以使用一个连接进行并行处理)。
  • 标头压缩以减少开销。
  • 从服务器主动“推送”响应到客户端缓存。

HTTP/2:优缺点

优点

  • 所有浏览器都支持 HTTPS 上的 HTTP/2 协议并安装了 SSL 证书。
  • HTTP/2 允许客户端通过单个 TCP 连接同时发送所有请求。从理论上讲,客户端应该更快地接收资源。
  • TCP 是一种可靠、稳定的连接协议。

缺点

  • 并发请求会增加服务器的负载。HTTP/2 服务器可以接收大批量的请求,这会导致请求超时。服务器负载激增的问题可以通过插入负载均衡器或代理服务器来解决,这可以限制请求。
  • 服务器对 HTTP/2 优先级的支持还不成熟。软件支持仍在不断发展。某些 CDN 或负载平衡器可能无法正确支持优先级排序。
  • HTTP/2 推送功能可能很难正确实现。
  • HTTP/2 解决了 HTTP 队头阻塞问题,但 TCP 级阻塞仍然会导致问题。

HTTP/2 适用于哪些用例?

HTTP/2 支持 HTTP/1.x 的所有用例,无论它是在浏览器中实现的,包括桌面 Web 浏览器、移动 Web 浏览器、Web API 和 Web 服务器。但是,它也可以用于代理服务器、反向代理服务器、防火墙和内容分发网络,以及以下情况:
  • 对于响应时间不重要的应用程序。
  • 仅在使用合适的自适应技术(例如WebSockets、服务器发送事件 (SSE)、发布-订阅 (pub/sub)消息传递)的情况下,才能使用时间关键型应用程序,例如实时消息传递或流式应用程序。
  • 需要可靠连接的地方(TCP 的强度)
  • 使用受限的 IoT 设备

HTTP/3 概述

HTTP/3 支持快速、可靠和安全的连接。默认情况下,它使用 Google 的 QUIC 协议对 Internet 传输进行加密。

HTTP/3:优缺点

优点

  • 在 UDP 上运行的新(不同的)传输协议 QUIC 的引入意味着在理论上和目前在实验上都减少了延迟。
  • 由于 UDP 不在协议栈中执行错误检查和纠正,因此适用于不需要或在应用程序中执行这些的用例。这意味着 UDP 避免了任何相关的开销。UDP 通常用于时间敏感的应用程序,例如实时系统,它不能等待数据包重新传输,因此可以容忍一些丢弃的数据包

缺点

  • 传输层分支。过渡到 HTTP/3 不仅涉及应用层的变化,还涉及底层传输层的变化。因此,与其前身相比,采用 HTTP/3 更具挑战性。
  • 可靠性问题。UDP 应用程序往往缺乏可靠性,它必须接受一定程度的数据包丢失、重新排序、错误或重复。由最终用户应用程序提供任何必要的握手,例如已收到消息的实时确认。

HTTP/3 适用于哪些用例?

  • 在线游戏、广告投标和 IP 语音等实时应用程序,以及使用实时流协议的地方。
  • 多种服务发现中的广播信息和精确时间协议、路由信息协议等共享信息。这是因为 UDP 支持多播。
  • 物联网。HTTP/3 可以解决物联网用例的无线连接有损问题,例如从附加传感器收集数据的移动设备。
  • 大数据。随着 HTTP/3 变得足够强大,托管的 API 服务将能够被流式传输,然后随着数据转化为商业智能而货币化。
  • 基于网络的虚拟现实。VR 应用程序需要更多带宽来呈现虚拟场景的复杂细节,并且肯定会从迁移到由 QUIC 支持的 HTTP/3 中受益。
  • 微服务:更快(或没有)握手意味着更快地遍历微服务网格。

编程语言对HTTP/2和HTTP/3的支持

.NET 中对HTTP/2和HTTP/3的支持

ASP.NET Core 2.2,开始对 HTTP/2 的支持
ASP.NET Core 3.0,默认启用HTTP/2
ASP.NET Core 5.0,性能改进
ASP.NET Core 6.0,包含对HTTP/3支持的实验功能
ASP.NET Core 7.0,HTTP/2性能改进
ASP.NET Core 8.0-preview 1,默认启用HTTP/3HTTP/2 在MacOS受支持

Golang对HTTP/2 和 HTTP/3的支持

  1. 从Go 1.6开始,当时使用HTTPS时,net/http package 开始支持HTTP/2
  2. 对于HTTP/3的支持,仅限Go 1.18.x 和1.19.x,目前没有发布1.0版本的quic-go/http3版本,并且关于net/http:suuport HTTP/3的issues还未关闭

一些包含HTTP/3客户端和服务端实现方案的开源库

Name Client Server Programming language Company Repository
lsquic Yes Yes C LiteSpeed https://github.com/litespeedtech/lsquic
nghttp3 Yes Yes C   https://github.com/ngtcp2/nghttp3
h2o No Yes C   https://github.com/h2o/h2o
libcurl[29][30] Yes No C   https://github.com/curl/curl
MsQuic[31] Yes Yes C Microsoft https://github.com/microsoft/msquic
proxygen Yes Yes C++ Facebook https://github.com/facebook/proxygen#quic-and-http3
Cronet Yes Yes C++ Google https://github.com/chromium/chromium/tree/main/net/quic
.NET[32] Yes Yes C# (using MsQuic)[33] Microsoft https://github.com/dotnet
quic-go Yes Yes Go   https://github.com/quic-go/quic-go
http3 Yes Yes Haskell   https://github.com/kazu-yamamoto/http3
Kwik Yes Yes Java   https://github.com/ptrd/kwik
Flupke Yes Yes Java   https://bitbucket.org/pjtr/flupke
aioquic Yes Yes Python   https://github.com/aiortc/aioquic
quiche Yes Yes Rust Cloudflare https://github.com/cloudflare/quiche
neqo Yes Yes Rust Mozilla https://github.com/mozilla/neqo
quinn Yes Yes Rust   https://github.com/quinn-rs/quinn
s2n-quic Yes Yes Rust Amazon Web Services https://github.com/aws/s2n-quic

Server 对HTTP/3的支持

  • 2021 6月7日,LiteSpeed Web Server(和OpenLiteSpee)6.0.2发布,成为第一个默认启用HTTP/3的版本。
  • Caddy web服务器v2.6.0(2022年9月20日发布)默认启用HTTP/3。
  • Nginx对HTTP/3的支持正在研究中。2020年6月发布了支持HTTP/3的Nginx技术预览。
  • Cloudflare为nginx发布了一个补丁,将quiche HTTP/3库集成到其中。
  • Microsoft IIS对HTTP/3的支持是通过Windows Server 2022/Windows 11本地启用的。
  • 自2022年5月31日发布2.6版以来,HAProxy支持基于QUIC的HTTP/3。

浏览器对HTTP/2 HTTP/3的支持

 
主流浏览器Chrome Edge Safari对HTTP/2支持良好,但是对于HTTP/3Safari明显落后。
像Google,Facebook这些互联网巨头也都在使用HTTP/3,并且HTTP/3流量占比高。

HTTP/3的实际应用

来自万维网技术调查网站的一份调查显示,25.2%的受调查的网站(数百万的样本数规模)使用HTTP/3。

实施HTTP/2/3的挑战

HTTP/2 要求TLS1.2+,而HTTP/3要求TLS1.3,这对于大多数落后的系统而言升级HTTPS,并且要求支持较高版本的TLS版本很难,因为无法合适的协商加密套件 TLS1.3在Windows 7是没办法支持的,而要支持TLS1.2也需要开放更多已经被证明存在安全漏洞的加密套件。总言之,兼容性和安全性之间的矛盾让实施HTTP/2/3带来了巨大的挑战。参考阅读

HTTP/3是不是会替换HTTP/2?

HTTP/3 提供了大量的性能和安全改进,这是互联网下一阶段发展所需要的。尽管如此,尽管事实上存在对 HTTP/2 增强的明显需求,但对于 HTTP/3 是否会最终成为 HTTP/2 网络状态的全面改进尚无定论。
此外,使用 QUIC协议UDP(而不是 TCP)迁移到 HTTP/3 在具有可靠互联网连接的用例中留下了一些 QoS 问题。这增加了使用新兴协议所固有的不确定性。
HTTP/3 是Web 协议的一项激动人心的新发展,它将成为许多当前或未来用例的合适解决方案。但它旨在改进的标准还有很多生命,而且 HTTP/2 不会很快消失。
 

随机推荐

  1. Zabbix与乐维监控对比分析(一)——架构、性能篇

    近年来,Zabbix凭借其近乎无所不能的监控及优越的性能一路高歌猛进,在开源监控领域独占鳌头:而作为后起的新锐IT监控平台--乐维监控,则不断吸收Zabbix,Prometheus等优秀开源平台的优点 ...

  2. WeakHashMap 和 HashMap 的区别是什么,何时使用?

    本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 提问. 前言 大家好,我是小彭. 在之前的文章里,我们聊到了 Java 标准库中 HashMap 与 LinkedH ...

  3. C++编程笔记(STL学习)

     一.顺序容器   1.1.vector   1.2.dequeue   1.3.list  二.关联性容器   2.3.set   2.3.map  三.算法   3.1.遍历算法(for_each ...

  4. Redis分布式锁应用

    Redis锁的使用 起因:分布式环境下需对并发进行逻辑一致性控制 架构:springboot2.Redis IDEA实操 先新建RedisLock组件 注:释放锁使用lua脚本保持原子性 @Compo ...

  5. python中函数教程

    函数的基本概念 1.什么是函数? 函数相当于一种工具,就是把一串代码装到一起,我们下次需要用的这个功能的时候可以直接使用 函数相当于是工具(具有一定功能) 不用函数 修理工需要修理器件要用锤子 原地打 ...

  6. express 为所有路由添加 405 method not allowd 响应

    背景知识 HTTP Status Code 405 405 Method not allowed The resource was requested using a method that is n ...

  7. .net做一个基于ChatGpt的微信机器人吧~[全教程]

    最近这个ChatGPT很火啊,看了B站上很多视频,自己非常手痒,高低自己得整一个啊,很多人都是把ChatGPT和微信结合在一起,正巧我是Wechaty框架的.net sdk贡献者,这不是一应俱全了吗? ...

  8. 《HTTP权威指南》– 5.Web服务器

    Web服务器概念: 实现了HTTP和相关的TCP连接处理,负责管理Web服务器提供的资源,以及对Web服务器的配置.控制及扩展方面的管理. 各种不同的形式: 通过软件Web服务器:运行在标准的.有网络 ...

  9. Linux NTP工具的基本使用

    NTP 时间同步 NTP(Network Time Protocol)协议,网络时间协议.利用ntp协议可以实现网络中的计算机时间同步. 实现NTP协议的工具: ntpdate:只能同步一次时间 nt ...

  10. 重学c#系列——linq(2) [二十八]

    前言 前文提及到了一些基础的linq的基础,那么这一节是一些补充. 正文 关于一个orderby的问题. 比如我们输入两个order by. 这里告诉我们多个order by是没有意义的,如果多个那么 ...