Nginx官方今年推出了一个nginx-quic以支持全新的QUIC+HTTP/3传输协议。
HTTP/3的前世今生
在当下技术飞速发展,高频迭代的今天,超文本传输协议HTTP是过去的二十多年来保持稳定的少数技术之一。
HTTP/1.1标准于1999年发布,是现在Web应用程序和API中无所不在的传输协议。尽管其传输的应用程序和服务都发生了巨大变化,但该协议在21年以来基本保持未变。
为什么这么说呢?
不是有HTTP/2么?
HTTP/2标准于2015年出版,并且目前已经有45%的网站已经采纳使用了HTTP/2。但这只是一方面,一个端点, "最后一英里"的一头。在另一头现代公共Internet上HTTP的使用则有很大不同。现代Internet基础结构的现实情况是HTTP/2很少实现端到端两头都部署。在公共Internet上最明显体现的问题是网络延迟非常高,并且一个HTTP请求的问题可能会导致后续请求被延迟。在应用程序运行时环境(例如,公共云或私有数据中心)内部,延迟低,网络可靠性非常高,并且直接检查HTTP/1.1的基于文本的传输流的能力比效率更高。
HTTP/2的二进制传输流。
HTTP/2极大地改善了浏览器和移动设备上的用户体验,因为它非常适合客户端和运行时基础结构的边缘之间的环境。它通常被代理到使用HTTP/1.1的运行时环境中。
边缘节点很可能是CDN(代理)供应商,或处理进入运行时环境的流量的反向代理负载平衡器。
为什么要提出另一个新协议HTTP/3?
HTTP/2的主要创新是用TCP作为低级传输的单个连接上复用多个HTTP请求。
不幸的是,TCP具有固有的局限性,限制了网站和应用程序的性能以及用户体验。在TCP标准最初发表于1981年,一直以来非常安全并且好用,是无可替代的通用的传输协议。
但是,当在同一连接上多路复用多个独立请求时,它们会受到该连接可靠性的约束。如果仅一个请求的数据包丢失,则所有多路复用请求都会延迟,直到首先检测到丢失的数据包,然后重新传输。
QUIC,UDP和TSL 1.3
QUIC使用UDP作为在客户端和服务器之间移动数据包的低级传输机制,实现了发出HTTP请求的可靠连接。最重要的是QUIC还将TLS层作为内置成分进行了统一集成(TLS 1.3),通过缓存和复用,极大的提高其效率,而非HTTP/1.1和HTTP/2那样作为附加层。
TLS1.3,服务器和客户端进行首次握手会话之后,就可以缓存会话密钥。在新请求时,就可以直接使用缓存的建立会话,而不需要会话握手,实现0-RTT。
HTTP3和客户端支持
QUIC的目标是为HTTP/3提供高性能,高可靠性,高安全性的传输协议(尽管QUIC也适用于非HTTP流量)。从语义上讲,HTTP/3本身与HTTP/2非常相似。客户端(Web浏览器)如何知道要使用哪个HTTP版本?
HTTP/2的引入首先引起了版本控制问题,HTTP/2通过使用TLS握手来检测客户端和服务器是否能够通过HTTP/2进行通信来解决该问题。这样,客户端甚至在建立连接之前就知道如何与服务器对话。但是,QUIC使用UDP代替TCP作为基础传输协议提出了一个新的挑战:客户端如何知道最初要请求哪种连接类型(TCP或UDP)?
解决方案是让客户端为初始HTTP请求建立TCP连接。支持HTTP/3的服务器的响应头中会包括Alt-Svc标头,用于指定侦听HTTP/3流量的UDP端口。此外,浏览器还会记忆哪些站点支持QUIC,避免一直使用Alt-Svc方法。
nginx-quic预览版
nginx-quic是NGINX的官方QUIC和HTTP/3实现的初始版本,即http_v3_module。这是一项技术预览,是实验性的版本,不适用于生产环境。nginx-quic基于QUIC草案的子集实施的。
经过几个月的设计和开发,http_v3_module已准备好进行互操作性测试。
请注意,NGINX开源主线开发分支(也不包括NGINX Plus的任何发行版)中暂不提供http_v3_module。h目前还位于nginx-quic的专用开发分支。另外,nginx-quic的QUIC + HTTP/3实现是全新的,与Cloudflare quiche项目实现的补丁程序也无关。
启用QUIC+HTTP/3非常简单,配置如下:
server {
listen 443 ssl; # HTTP/1.1的TCP监听端口
listen 443 http3 reuseport; # QUIC+HTTP/3的UDP监听
ssl_protocols TLSv1.3; # QUIC 必须使用TLS 1.3
ssl_certificate ssl/www.35e.net.crt;
ssl_certificate_key ssl/www.35e.net.key;
add_header Alt-Svc 'quic=":443"'; # 必须添加的Alt-Svc响应头
add_header QUIC-Status $quic; # 必须添加的QUIC状态头
}
诚信为本,卓越品质,做行业领跑者