一文带你从了解到搭建 HTTP/3 Web 服务

By 李崇民 2023-08-26

NGINX 向云原生演进,All in OpenNJet


HTTP 是互联网的重要骨干,通俗点说,就是它让用户能够加载网站。经过多年的发展,HTTP 已经从 HTTP/1.0 发展到 HTTP/1.1,HTTP/2,再到如今的 HTTP/3,每一次的迭代,都会添加新功能满足当代的需求,比如安全、会话处理、应用程序层的要求。

img

从 HTTP/1.0 到 HTTP/2 ,HTTP 协议已经做了三次升级,但是流水的 HTTP,铁打的 TCP,因为 TCP 协议更加可靠,然而 HTTP/2 刚刚推出没多久,就已经有公司开始大力研发 HTTP / 3 。随着互联网流量的不断增长,应用需求的不断增加,HTTP/2 的缺点也越来越明显。

首先,HTTP/2 的最终版本并没有包含许多人们希望在 HTTP/1.1 基础上进行的改进。为了保持与 HTTP/1.1 的向后兼容,协议必须保留相同的 POST 请求 GET 、状态代码(200、301、404 和 500)等。

此外,一些已实现的功能还引入了安全问题。除了遗留的缺乏强制加密之外,还包括容易受到攻击的压缩页面标头和 cookie。

HTTP/3 的目标则是通过解决 HTTP/2 的传输相关问题,在所有形式的设备上提供快速、可靠且安全的 Web 连接。为此,它使用了一种名为 QUIC 的新传输层网络协议,该协议在用户数据报协议 (UDP) 上运行,而不是以前版本的 HTTP 使用的 TCP。

为什么 HTTP/3 很重要?

HTTP/3 功能的优势来自于底层的 QUIC 协议。QUIC(快速 UDP 互联网连接)是一种新的传输方式,与 TCP 相比,它减少了延迟。从表面上看,QUIC 与 UDP 上实现的 TCP + TLS+ HTTP / 2 非常相似。由于 TCP 是在操作系统内核和中间设备固件中实现的,因此几乎不可能对 TCP 进行重大更改。但是,由于 QUIC 建立在 UDP 之上,因此它没有这样的限制。

img

QUIC 相对于现有 TCP + TLS + HTTP2 的主要功能改进包括

  • 采用 TLSv1.3,显著缩短连接建立时间
  • 改进拥塞控制
  • 多路复用,解决队头阻塞
  • 前向纠错
  • 连接迁移

TCP 必然是存在局限性的:

  • 可能会间歇性地挂起您的数据传输;
  • 不支持流级多路复用;
  • 导致冗余通信;

QUIC 协议通过在底层传输机制中引入一些更改来解决这些 TCP 限制。

TCP 已被证明是支持互联网流量增长的非常强大的传输协议。但是,根据设计,TCP 从来不适合处理有损无线介质上的数据传输。在互联网的早期,有线连接是唯一存在的连接,连接每台联网的计算机,所以这从来都不是问题。

现在,智能手机和便携式设备比台式机和笔记本电脑更多,超过 50% 的互联网流量是通过无线传输的。随着这种增长,随着响应时间的增加,整体 Web 浏览体验已经恶化。有几个因素导致了这种情况,其中最重要的是无线覆盖不足时的队头阻塞。

谷歌将 QUIC 作为一些流行的 Google 服务的底层传输协议大大提高了响应速度和用户体验。通过将 QUIC 部署为流媒体 YouTube 视频的底层传输协议,谷歌报告称重新缓冲率下降了 30%,这对视频观看体验产生了直接影响。

HTTP/3 的最佳用例

HTTP/3 的目的是改善整体网络体验,特别是在高速无线互联网接入仍然不可用的地区。尽管 HTTP/2 非常适合其中一些应用程序,但 HTTP/3 在以下场景中增加了价值。

1280X1280 (2)

HTTP 可能不是物联网的首选协议,但有些应用程序非常适合基于 HTTP 的通信。例如,HTTP/3 可以解决从连接的传感器收集数据的移动设备的有损无线连接问题。这也适用于安装在车辆或可移动资产上的独立物联网设备。由于 HTTP / 3 具有强大的传输层,因此通过 HTTP 访问此类设备更可靠。

实时广告竞价

当广告投放到网络浏览器时,系统会实时出价。 页面和用户信息被发送到广告交易平台,然后由广告交易平台将其拍卖给出价最高的广告客户。 所有可以向消费者投放广告的公司都出价成为给人留下这种印象的公司。 这是对广告服务网络提供的空间的算法竞争。

拥有只需要一次确认(一次握手)的连接可以极大地提高出价的性能,并允许出价加载得更快,确保页面加载不会因这一系列竞争而延迟,更快的广告加载需要更快的页面加载。

微服务

在微服务网格中,为了获取数据,会浪费大量时间浏览所有微服务。 HTTP 始终是最慢的跃点。 因此,在每个系统之间发出每个请求的速度越快(以千分之一秒而不是百分之一秒为单位),数据隔离效果就越好,网络上的复制数据数量就越少。

QUIC 协议的优势是握手次数相对较少,因此你可以在个位数毫秒内就把这些请求传递出去,并且你的微服务可以更纯粹,从而实现真正的单一责任。这里使用 HTTP/3 的好处更多是来自于快速完成每个微交互 ,少量来自于访问大数据时的高吞吐量。

如何基于 OpenNJet 搭建 HTTP/3 Web 服务

来测试您网站的速度以及互联网连接的速度

在 CentOS 7 下的 HTTP/3 测试工具可从 Gitee 下载

HTTP3 配置示例

helper broker modules/njt_helper_broker_module.so
conf/mqtt.conf;
helper ctrl modules/njt_helper_ctrl_module.so
conf/ctrl.conf;

load_module modules/njt_http_split_clients_2_module.so;
load_module modules/njt_agent_dynlog_module.so;
load_module modules/njt_http_location_module.so; 
load_module modules/njt_http_dyn_bwlist_module.so; 

load_module modules/njt_dyn_ssl_module.so;
load_module modules/njt_http_vtsc_module.so;

cluster_name helper;
node_name node1;
worker_processes auto;   
error_log  logs/error.log info;

events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

    server {
        server_name  localhost;

        # for better compatibility we recommend
        # using the same port number for QUIC and TCP
        listen 8443 quic  reuseport; # QUIC
        listen 8443 ssl;             # TCP
        ssl_protocols       TLSv1.3;

            location / {
                # advertise that QUIC is available on the configured port
                add_header Alt-Svc 'h3=":$server_port"; ma=86400';
                    root   html;
                    index  index.html index.htm;           
            }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

     }

}

测试HTTP3功能

在centos7下的http3测试工具可从Gitee https://gitee.com/njet-rd/http3-tools 下载

基于curl_http3 测试HTTP3
curl-http3 -vs -D/dev/stdout -o/dev/null --http3 https://quic.nginx.org
* processing: https://quic.nginx.org
*   Trying 35.214.218.230:443...
*  CAfile: /etc/pki/tls/certs/ca-bundle.crt
*  CApath: none
*   Trying 35.214.218.230:443...
......
> Accept: */*
>
< HTTP/3 200
HTTP/3 200
......
基于hey进行压测
hey -n 10 -c 5 -h3  https://quic.nginx.org
Summary:
  Total:        5.8759 secs
  Slowest:      3.9820 secs
  Fastest:      0.5170 secs  
  Average:      1.7755 secs  
  Requests/sec: 1.7019  
  Total data:   25190 bytes  
  Size/request: 2519 bytes

Response time histogram:
  0.517 [1]     |■■■■■■■■■■■■■  
  0.863 [1]     |■■■■■■■■■■■■■  
  1.210 [1]     |■■■■■■■■■■■■■  
  1.556 [2]     |■■■■■■■■■■■■■■■■■■■■■■■■■■■  
  1.903 [3]     |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■  
  2.250 [0]     |  
  2.596 [0]     |  
  2.943 [0]     |  
  3.289 [1]     |■■■■■■■■■■■■■  
  3.636 [0]     |  
  3.982 [1]     |■■■■■■■■■■■■
......
基于浏览器访问HTTP3
在浏览器输入   https://www.tmlake.com:8443/

http3配置指令

开启、关闭http3功能

Syntax:	"http3 on | off;
"
Default:	http3 on;
Context:	http, server

开启、关闭对QUIC协议对HTTP/0.9功能的支持

Syntax:	"http3_hq on | off;
"
Default:	http3_hq off;
Context:	http, server

设置在一个Connection内允许的请求stream数目最大值

Syntax:	"http3_max_concurrent_streams number;
"
Default:	http3_max_concurrent_streams 128;
Context:	http, server

设置在读写QUIC streams时的缓冲区大小

Syntax:	"http3_stream_buffer_size size;
"
Default:	http3_stream_buffer_size 64k;
Context:	http, server

设置在Server端保存客户端Cid数目的最大值

Syntax:	"quic_active_connection_id_limit number;
"
Default:	quic_active_connection_id_limit 2;
Context:	http, server

开启、关闭ebpf支持

本功能只在 Linux 5.7+ 以上内核版本中支持

Syntax:	"quic_bpf on | off;
"
Default:	quic_bpf off;
Context:	main

开启关闭GSO功能

本功能只在支持UDP_SEGMENT功能的Linux(>= 4.18)版本中支持

Syntax:	quic_gso on | off;
Default:	quic_gso off;
Context:	http, server

设置host_key文件

设置文件保存在加密状态重置(encrypt stateless reset)及地址验证令牌(address validation tokens)过程中要用到的密钥。缺省情况下,这个密钥会随机产生。

Syntax:	"quic_host_key file;
"
Default:	——;
Context:	http, server

开启关闭地址验证QUIC Address Validation 特性

Syntax:	quic_retry on | off;
Default:	quic_retry off;
Context:	http, server

使用第三方工具

目前最新版本的 Firefox 和 Chrome 浏览器都已经支持 QUIC 协议,可参考对应的文档开启 QUIC 协议支持。在测试时,首次连接时,使用的协议可能会是 HTTP1 或 HTTP2,这时可以多刷新几次,就会看到网页传输是使用 HTTP3 协议完成的。此外也可以利用 https://http3check.net/ 来测试你的实现。

http3check.net 测试结果

image-20230612141122763

HTTP/3 Statistics
Zero Round Trip Time Resumption (0-RTT)
The QUIC handshake for this connection was completed without any additional round-trips.

SUCCESS
QUIC Versions
These are the QUIC versions supported by this QUIC endpoint.

AGREED SUPPORTED
Connection ID
This unique identifier for a QUIC connection is used to ensure that changes to an endpoint's lower network layer address (UDP/IP) does not affect the delivery of the QUIC connection's packets.

This tool attempts two connections to test the server's 0-RTT capabilities. During the first connection, the client receives important handshake material from the server. With 0-RTT, the client can start to send data immediately if it uses this handshake material when it creates the second connection.

Packet RX
This value represents the time between the first packet sent and the first packet received (measured in milliseconds).

Handshake Done
This value represents the time between when the first packet is sent and when the handshake is completed (measured in milliseconds).

Take notice of the difference in this metric between the first connection and the second connection. Using 0-RTT, future connections (i.e. the second connection) can complete the handshake much faster than the original connection.

QLog
QLog is a standard under development for QUIC Connection debugging and visualization. Learn more at https://quic.edm.uhasselt.be/

To view or download the raw QLog ("application/json"), add "format=qlog" to the HTTP query string.


HTTP/3 为 Web 应用程序提供了比 HTTP/2 更多的好处,特别是在性能、安全性和兼容性方面。目前谷歌、Meta、微软、Akamai、Cloudflare、Fastly、NGINX 和爱立信等大型科技公司已经在大量使用它。

HTTP/3 真的来了!