为优化全链路耗时,尽可能缩短建连时间,实践下H3.
H3是否能打通,可以拆分为3块
- 服务端支持H3协议
- H3链路是否畅通
- 客户端/Chrome需要支持H3协议
服务端支持H3协议
以 Nginx 为例,其他同理。默认站点已支持H2,且TLS版本支持1.3。
必要配置
- 开启监控
1
| listen 443 quic reuseport;
|
- add_header
1
| add_header alt-svc 'h3=":443"; ma=2592000, h3-29=":443"; ma=2592000, h3-Q050=":443"; ma=2592000, h3-Q046=":443"; ma=2592000, h3-Q043=":443"; ma=2592000, quic=":443"; ma=2592000; v="43,46"';
|
nginx.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| server { listen 80; listen 443 ssl ; #listen [::]:443 ssl; listen 443 quic reuseport; #listen [::]:443 quic reuseport; http2 on; server_name rencheng.cc www.rencheng.cc; index index.php index.html index.htm default.php default.htm default.html; root /www/wwwroot/rencheng.cc; #SSL-START SSL相关配置,请勿删除或修改下一行带注释的404规则 #error_page 404/404.html; #HTTP_TO_HTTPS_START if ($server_port !~ 443){ rewrite ^(/.*)$ https://$host$1 permanent; } #HTTP_TO_HTTPS_END ssl_certificate /www/server/panel/vhost/cert/rencheng.cc/fullchain.pem; ssl_certificate_key /www/server/panel/vhost/cert/rencheng.cc/privkey.pem; ssl_protocols TLSv1.3; ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; #ssl_early_data on; add_header Strict-Transport-Security "max-age=31536000"; add_header alt-svc 'h3=":443"; ma=2592000, h3-29=":443"; ma=2592000, h3-Q050=":443"; ma=2592000, h3-Q046=":443"; ma=2592000, h3-Q043=":443"; ma=2592000, quic=":443"; ma=2592000; v="43,46"'; error_page 497 https://$host$request_uri; #SSL-END #ERROR-PAGE-START 错误页配置,可以注释、删除或修改 error_page 404 /404.html; error_page 502 /502.html; #ERROR-PAGE-END #PHP-INFO-START PHP引用配置,可以注释或修改 include enable-php-00.conf; #PHP-INFO-END #REWRITE-START URL重写规则引用,修改后将导致面板设置的伪静态规则失效 include /www/server/panel/vhost/rewrite/rencheng.cc.conf; #REWRITE-END #禁止访问的文件或目录 location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md) { return 404; } #一键申请SSL证书验证目录相关设置 location ~ \.well-known{ allow all; } location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { expires 30d; error_log /dev/null; access_log /dev/null; } location ~ .*\.(js|css)?$ { expires 12h; error_log /dev/null; access_log /dev/null; } access_log /www/wwwlogs/rencheng.cc.log; error_log /www/wwwlogs/rencheng.cc.error.log; }
|
确保H3链路畅通
服务侧各节点防火墙开启udp流量
- 云实例的安全防火墙
- 服务器内防火墙打开,以宝塔为例
确保网络中间链路畅通
- 路由器支持udp流量
- 代理服务器支持udp流量
- 本地是否开启了代理(如果开启,需要关闭,目前为止大部分代理工具不支持udp流量转发)
- 首次使用流量测试,避免因为不确定WIFI连接的链路是否支持
测试H3是否连通
使用外部测试站点http3check.net
测试通过后,Chrome 需要设置开启 HTTP3,在chrome地址栏输入chrome://flags
,搜索Experimental QUIC protocol
,将default
改为enable
后重启即可。
多次清除缓存确认是否支持H3
iOS客户端支持H3
技术选型
- 方案一:由于iOS系统URLSession是在
iOS 14.5
开始支持的,如果仍然想使用URLSession的方式请求,并不能覆盖老系统。推荐等级⭐️⭐️。
- 方案二:使用Cronet,该方案的思路是通过URLProtocol的方式拦截到所有请求后,重定向到其内部发送H3请求,但需要研发对源码熟悉后精简功能,以减少对包体积的影响。。推荐等级⭐️⭐️⭐️。
- 无用的内部逻辑,例如 HTTP 模块里包含了很多浏览器才会用到的代码和功能;无
- 需用到的的协议,例如 FTP、Websocket 等;
- 与 quic 无关的功能模块,例如 tcp 连接池等。
- 方案三:使用大厂对Cronet精简过的库,优势是可以轻松迁移新版本,且大厂对其增加了很多功能,但是其对客户端支持还不完善,需要后续支撑好再进行接入是最好的。推荐等级⭐️⭐️⭐️⭐️。
架构低成本实践路线
- 先使用Apple的API让高版本系统客户端使用
- Cronet接入(缺点:包体积会增大)
- 接入成熟的大厂框架(减少包体积,体验一些实用功能)
在iOS上的实践
详见DEMO