虽然HTTP/3确实有一些很有前途的新概念,但不幸的是,它们对大多数网页和用户的影响可能相对有限(但可能对少数人至关重要)。HTTP/3的设置和使用(正确)也非常具有挑战性,因此在配置新协议时要小心。Part1:HTTP/3HistoryandCoreConcepts对http2的误解\不切实际的期望severpush在实践中行不通数据流和优先级往往难以实现在某些情况下(减少)资源包大小甚至拆分调整仍然是很好的做法协议行为。其他机制,如预加载,通常包含隐藏的深度和错误,使它们难以正确使用。(概念补充preload和prefetch)(HTTP/2和HTTP/3协议栈对比)协议分层是为了复用,其中TCP协议保证完整传输。QUIC(https://www.rfc-editor.org/rf...)协议之所以被提出,是因为早期的TCP并没有真正考虑最大效率。TCP需要每次往返时间(RTT)可能需要100毫秒以上的“握手”,从而导致严重延迟(如果一个文件的TCP数据包丢失,所有其他文件也将被延迟,直到这些数据包被恢复。)基本概念很难直接在HTTP/2中优化,因此我们重新构想并实现了一个更高级的TCP版本,并把它叫做QUIC。因为我们想让QUIC更容易部署,所以我们在UDP上运行它。我们对HTTP/3感到兴奋的主要特性(更快的连接设置、更少的HoL阻塞、连接迁移等)实际上都来自QUIC。QUIC使用UDP,因此设计HTTP/3的主要目的是希望它能使它们更易于部署,因为互联网上几乎所有设备都知道并实现了UDP。在UDP之上,QUIC基本上重新实现了TCP的功能。QUIC是万无一失的,它使用接收到的数据包的确认和重新传输来确保丢失的数据包仍然到达。QUIC还建立连接并进行高度复杂的握手。QUIC还使用所谓的流量控制和拥塞控制机制来防止发送方或接收方过载,但这也使得TCP比原始UDP慢。(TLS、TCP和QUIC握手持续时间)鉴于这种向永远在线的TLS(尤其是网络流量)的明显演变,QUIC的设计者决定将这一趋势提升到一个新的水平也就不足为奇了。他们没有简单地为HTTP/3定义明文模式,而是选择将加密深深植入QUIC本身,这打破了协议栈中协议之间典型的干净分离。(与TCP+TLS不同,QUIC还在数据包标头和有效负载中加密其传输层元数据。)优点缺点优点QUIC对其用户来说更安全。无法运行明文QUIC,因此攻击者和窃听者的监听选项更少。(最近的研究表明HTTP/2的明文选项有多么危险。)QUIC的连接建立速度更快。对于TLS-over-TCP,两种协议都需要自己单独的握手,而QUIC将传输和加密握手合二为一,从而节省了往返次数(见上图)。QUIC可以更容易地进化。因为它是完全加密的,所以网络中的中间件无法再像使用TCP那样观察和解释其内部工作原理。因此,它们也不会由于更新失败而(意外地)在较新版本的QUIC中中断。如果我们以后想给QUIC添加新的功能,我们“只需要”更新终端设备,而不是所有的中间件。缺点许多网络对允许QUIC犹豫不决。公司可能希望在他们的防火墙上阻止它,因为检测不需要的流量变得更加困难。ISP和中介网络可以阻止它,因为平均延迟和数据包丢失百分比等指标不再容易获得,这使得检测和诊断问题变得更加困难。这一切都意味着QUIC可能永远无法普遍使用。QUIC具有更高的加密开销。QUIC使用TLS来加密每个单独的数据包,而TLS-over-TCP可以同时加密多个数据包。对于高吞吐量场景,这会使QUIC变慢。QUIC使网络更加集中。我收到的一个常见抱怨是,“谷歌正在推动QUIC,因为它允许他们完全访问数据,同时不与任何其他人共享任何数据”。我主要不同意这一点。首先,与TLS-over-TCP(QUIC保持原样)相比,QUIC不会向外部观察者隐藏更多(或更少!)用户级信息(例如,您正在访问哪些URL)。特性解决HoL阻塞在传输层解决HoL阻塞是QUIC的主要目标之一。与TCP不同,QUIC非常清楚它是多路复用多个独立的字节流。(QUIC允许HTTP/3绕过队头阻塞问题。)QUIC支持连接迁移TCP协议下没有机制让客户端让服务器知道它改变了IP,所以每次网络改变都意味着即现有的TCP连接。重新启动TCP连接会产生严重后果(等待新的握手、重新启动下载、重新建立上下文)。为了解决这个问题,QUIC引入了一个新概念,称为连接标识符(CID)。每个连接都在4元组之上分配了另一个数字,该数字在两个端点之间唯一标识它。为了防止跟踪,QUIC会在每次使用新网络时更改CID。(QUIC使用多个协商连接标识符(CID)来防止用户跟踪)在TCP中,一个连接由四个参数定义(客户端IP地址+客户端端口+服务器IP地址+服务器端口),当端点改变网络时,这些参数会改变。因此,有时需要重新启动这些连接,从而导致停机。QUIC添加了另一个参数,称为连接ID。QUIC客户端和服务器都知道哪些连接ID映射到哪些连接,因此对网络变化更加健壮。QUIC灵活且可扩展QUIC几乎是完全加密的,这意味着如果我们想部署更新版本的QUIC,我们只需要更新端点(客户端和服务器),而不是所有的中间件。QUIC不使用单个固定的包头来发送所有协议元数据。相比之下,QUIC具有较短的数据包标头,并在数据包有效负载中使用各种“帧”(类似于微小的私有数据包)来传达附加信息。比如有ACK帧(确认),NEW_CONNECTION_ID帧(帮助建立连接迁移),STREAM帧(承载数据),如下图所示。QUIC使用自定义TLS扩展来携带所谓的传输参数。这些允许客户端和服务器为QUIC连接选择配置。这意味着他们可以协商启用哪些功能(例如,是否允许连接迁移、支持哪些扩展等)并传达某些机制的合理默认值(例如,支持的最大数据包大小、流量控制限制)。大多数实现目前都是在“用户态”中完成的(不像TCP,后者通常在“内核态”中完成)。虽然QUIC现在已经标准化,但它确实应该被视为QUIC1,其明确意图是创建版本2和更快的版本。第2部分:HTTP/3性能特性QUIC和HTTP/3确实具有巨大的Web性能潜力,但主要针对慢速网络上的用户。如果您的常客使用快速有线或蜂窝网络,他们可能不会从新协议中获益太多。拥塞控制性能的一个方面是传输协议如何有效地使用网络的全部(物理)带宽(即大约每秒可以发送或接收多少数据包)。进而影响页面资源的下载速度。有些人声称QUIC在某种程度上比TCP好得多,但事实并非如此。一个连接并不知道它可以预先安全或公平地使用多少带宽,并且该带宽会随着用户加入、离开和使用网络而变化。为了解决这个问题,TCP将不断尝试通过使用称为拥塞控制的机制来发现可用带宽。(TCP拥塞控制的简化示例,从10个数据包的发送速率开始)虽然TCP的拥塞控制使其具有鲁棒性,但这也意味着需要一段时间才能达到最佳发送速率,具体取决于RTT和实际可用带宽。对于网页加载,这种慢启动方法还会影响FCP(首次内容绘制)等指标,因为在前几次往返中仅传输少量数据(数十到数百KB)。并不是说QUIC没有使用拥塞控制,它实际上使用了与TCP非常相似的带宽管理技术。它还以低发送速率开始并随着时间的推移而增长,使用确认作为衡量网络容量的关键机制。拥塞控制算法今天仍在大力发展,例如,我们可能需要调整一些东西以充分利用5G。QUIC的延迟确认频率扩展建议虽然默认情况下QUIC每收到2个数据包就发送一次确认,但此扩展允许端点每10个数据包确认一次。这已被证明为卫星和超高带宽网络提供了很大的速度优势,因为传输确认数据包的开销减少了。将这样的扩展添加到TCP需要很长时间才能被采用,而使用QUIC则部署起来要容易得多。拥塞控制算法并不特定于TCP或QUIC;它们可以被任一协议使用,事实上,大多数生产级QUIC实现都有Cubic和BBR的自定义实现。0-RTT连接设置不支持在握手期间发送非TCP内容,因为TCP旨在不依赖TLS的情况下使用。这是低效的,因为在我们发送第一个HTTP请求之前会导致至少两次往返的握手延迟开销。QUIC从一开始就考虑到了TLS,因此将传输和加密握手结合在一个机制中。这意味着QUIC握手总共只需要一次往返,比TCP+TLS1.3少了一次往返。(TCP+TLS与QUIC连接设置)虽然最坏情况(TCP+TLS1.2,(a))QUIC比TCP快两个甚至三个往返,现代TCP+TLS1.3也“仅”两个往返(很少显示(b))会话恢复和0-RTT经常被误解为QUIC特定的特性。事实上,这些实际上是TLS功能,它们在TLS1.2中以某种形式存在,现在在TLS1.3中已经完全成熟。QUIC使用0-RTT的更快连接设置实际上更多的是微优化,而不是革命性的新功能。与最先进的TCP+TLS1.3设置相比,它最多可节省一次往返。第一次往返中实际可以发送的数据量也受到许多安全考虑的限制。因此,如果您的用户使用延迟非常高的网络(例如,RTT超过200毫秒的卫星网络),或者如果您通常不发送大量数据,则此功能将会大放异彩。在其他情况下,您最多只能获得几十毫秒,如果您已经在使用CDN,则甚至更少。UDP和TLS性能QUIC使用UDP和重新加密使其比TCP慢一点(但情况正在改善),因为TCP和UDP通常直接在操作系统的快速内核中实现。相比之下,TLS和QUIC实现主要在较慢的用户空间中。(TCP和QUIC的实现差异)对于TCP,这些开销比UDP低很多,主要是因为TCP在历史上被使用的次数远多于UDP。但在过去的五年中,大多数操作系统还增加了针对UDP的优化选项。其次,QUIC有很多开销,因为它单独加密每个数据包。在实践中,优化的加密库和允许批量加密QUIC数据包标头的巧妙方法。最近,Google的QUIC堆栈的优化版本目前比TCP+TLS慢约20%。第3部分:实用的HTTP/3部署选项你可能不知道使用HTTP/3时不需要对您的页面或资源进行任何更改!服务器和网络这些实现主要处理HTTP/3和QUIC的东西;它们本身并不是真正成熟的网络服务器。PythonaioquicGoquic-goRust(quiche)[https://github.com/cloudflare...](Cloudflare),Quinn,Neqo(Mozilla)C和C++mvfst(Facebook),MsQuic,(Microsoft),(Google),开箱即用的ngtcp2、LSQUIC(Litespeed)、picoquic、quicly(Fastly)完整Web服务器的部分列表及其当前的HTTP/3支持如下:Apache支持目前未知。什么都没有宣布。它还可能需要OpenSSL。(但请注意,有一个ApacheTrafficServer实现。)NGINX这是一个自定义实现。这是相对较新的,并且仍然是高度实验性的。预计到2021年底将合并到主线NGINX中。这是相对较新的,并且仍然是高度实验性的。请注意,还有一个补丁可以在NGINX上运行Cloudflare的quic库,目前可能更稳定。Node.js内部使用ngtcp2库。它被OpenSSL的进展所阻止,尽管他们计划切换到QUIC-TLS分支以更快地完成一些工作。IIS当前不知道IIS支持,也没有任何宣布。但是,它可以在内部使用MsQuic库。Hypercorn集成了aioquic,并提供实验支持。Caddy使用完全支持的quic-go。H2O使用速度非常快,并得到全面支持。Litespeed这使用LSQUIC,完全支持。大多数流行的浏览器已经(实验性)支持HTTP/3!参考资料[HTTP/3FromAToZ:CoreConcepts(Part1)](https://www.smashingmagazine....)HTTP/3:PerformanceImprovements(Part2)[HTTP/3:PracticalDeploymentOptions(Part)3)](https://www.smashingmagazine....)
