🤪亲 http/2和3 真会用吗?
背景
记录一下nginx配置
http/2
nginx 版本: > 1.9.5
server {
# 开启http2
listen 3839 ssl http2;
# http2 单连接处理请求数量,默认1k,达到上限会要求建立新的连接,http2_max_requests已废弃
keepalive_requests 10000;
# 并发HTTP / 2流的最大数量。
http2_max_concurrent_streams 128;
# 空闲断开时间,默认30s, http2_recv_timeout已废弃
client_header_timeout 10s;
# SSL证书
ssl_certificate /ssl/selfsigned.pem;
ssl_certificate_key /ssl/selfsigned.key;
}
注意: 浏览器中的 http2 必须的加 SSL,如果是服务之间调用则不需要,http2 与 SSL 是独立的两个东西不相关,但浏览器中 http2 强制必须加 SSL,非浏览器中使用可以不加 SSL
http1 效果图
htttp2 效果图
完美了
http/3
nginx 版本: >= 1.25.0 ( HTTP/3 仍处于实验阶段)
http3 比较特殊 走 UDP 协议并且强制使用 SSL 浏览器默认是 TCP 所以有个升级的过程,可以使用两个端口 A 升级到 B ,也可以使用 reuseport 参数端口复用
方式一,复用端口
server {
# 开启http3, reuseport 为共用端口,这样可以http2和http3共用一个端口了
listen 8080 quic reuseport;
# 兜底降级处理,如果没有此配置则只支持http3,浏览器默认还是走TCP所以,只能用其他端口的Alt-Svc字段指定升级到此端口或用支持http3的工具请求
listen 8080 ssl ;
# 启用http2
http2 on;
# 根据需要启用 QUIC 重试
quic_retry on;
# SSL证书
ssl_certificate /ssl/selfsigned.pem;
ssl_certificate_key /ssl/selfsigned.key;
# 告诉客户端支持http3 并且在3839端口,ma为有效期(单位s, 不写默认1天,别设置太长不然降级后必须失效才会升级)
add_header Alt-Svc 'h3=":8080"; ma=10'; # 不可设置多个版本,Chrome 124 测试设置设置 h3-27=:8080"; ma=10,h3-29=":8080"; ma=10 会导致不升级到h3
}
方式二,两个端口分开
例: 从 8081 升级到 8080
server {
# 开启http2
listen 8081 ssl;
# 开启http2,新版不写在listen中了
http2 on;
# http2 单连接处理请求数量,默认1k,达到上限会要求建立新的连接,http2_max_requests已废弃
keepalive_requests 10000;
# 并发HTTP / 2流的最大数量。
http2_max_concurrent_streams 1280;
# 空闲断开时间,默认30s, http2_recv_timeout已废弃
client_header_timeout 10s;
# SSL证书
ssl_certificate /ssl/selfsigned.pem;
ssl_certificate_key /ssl/selfsigned.key;
# 告诉客户端支持http3 并且在8080端口,ma为有效期单位秒
add_header Alt-Svc 'h3=":8080";ma=10';
}
server {
# 开启http3
listen 8080 quic;
# 根据需要启用 QUIC 重试
quic_retry on;
# SSL证书
ssl_certificate /ssl/selfsigned.pem;
ssl_certificate_key /ssl/selfsigned.key;
}
http3 效果(含升级过程)
浏览器会有一个升级的过程,当前浏览器支持服务端的 h3 协议版本时就会将新的请求切换到 h3, 所以会出现部分 http2 部分 http3
http/2 与 3 性能对比
上面,请求100个请求看不出差距,加到 1000 请求数量后对比
http1
没啥好说的,6 个连接一组,有连接复用请求排队情况
http2
http2 因为复用连接,但只有一个连接,数据包分片返回,而且是无序的,所以请求量大时数据包会被插队,加上单连接窗口大小和容错性,使得请求时间被拉长
http3(升级完成后测试)
http3 使用 UDP,没有连接阻塞所以.每个请求单独返回,大量并发时表现优秀
注意:
-
可能是 nginx 对 http3 支持是实验性的.所以偶尔会报错
ERR_QUIC_PROTOCOL_ERROR
后续请求就会降级,失败的请求不会自动重发 -
但是(巨坑!!!!) Alt-Svc 好像是独立工作的, 因为 Alt-Svc 设置了失效时间,当出现
ERR_QUIC_PROTOCOL_ERROR
导致降级,必须等待 Alt-Svc 过期才会去拿最新的 Alt-Svc,所以 Alt-Svc 失效时间别设置太长 -
每次 Alt-Svc 过期后都会进行一次降级再升级, http3 请求头中的 Alt-Svc 字段浏览器里好像无效,在 http2 和 http1 中有效
总结:
- http2 时在少量请求时相对于 http1 有一定提升.但并没有解决阻塞问题.在大量请求时还是会阻塞,并且单连接丢包会导致重发.使大量请求且网络环境不佳的情况下性能不及http1
- http3 使用 UDP 解决了阻塞问题,但不稳定.会出现反复降级,浏览器优先还是使用 TCP 保证兼容性,需要从 http1/2 升级到 http3,无法直接使用 http3
转载自:https://juejin.cn/post/7364614337371357223