7.7.6 TLS与HTTP/2性能与兼容性排查
TLS与HTTP/2性能与兼容性排查#
1. 原理草图与协议协商路径#
2. 环境与版本确认(含安装与编译检查)#
- 目标:确认 Nginx 编译是否支持 http2 与 openssl 版本,避免因版本不匹配导致降级或失败。
# 查看Nginx版本与编译参数
nginx -V 2>&1 | sed -n '1,3p'
# 预期:--with-http_v2_module;openssl >= 1.1.1(支持TLS1.3)
# 示例输出片段:
# nginx version: nginx/1.22.1
# built with OpenSSL 1.1.1w
# configure arguments: ... --with-http_v2_module ...
如需安装(以RHEL/CentOS为例)
# 安装官方源并安装nginx
yum install -y yum-utils
cat >/etc/yum.repos.d/nginx.repo <<'EOF'
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1
EOF
yum install -y nginx openssl
systemctl enable --now nginx
3. 常见症状与影响面(带验证命令)#
- 握手缓慢/失败:首次连接耗时高、偶发超时、客户端报错
bash # 观察握手耗时与证书链 time openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null - HTTP/2协商失败:浏览器回退到 HTTP/1.1
bash # 查看ALPN协商结果 curl -Iv https://example.com 2>&1 | grep -E "ALPN|HTTP/" # 预期:ALPN, server accepted to use h2 - 性能异常:QPS下降、TTFB升高、CPU飙升
bash # 查看活跃连接与请求分布 nginx -V 2>&1 | grep -q stub_status || echo "建议启用stub_status" curl -s http://127.0.0.1/nginx_status
4. 排查路径与关键命令(含命令解释)#
- 验证证书链与私钥匹配
# 获取证书链并检查有效期、域名
openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null \
| openssl x509 -noout -subject -issuer -dates
# 验证证书与私钥是否匹配(modulus一致)
openssl x509 -noout -modulus -in /etc/nginx/ssl/site.crt | openssl md5
openssl rsa -noout -modulus -in /etc/nginx/ssl/site.key | openssl md5
- 确认HTTP/2是否生效
# h2协商成功则返回:HTTP/2 200
curl -I --http2 https://example.com
- 定位是否被上游或CDN降级
# 对比直连源站与经CDN的协议
curl -I --http2 https://origin.example.com
curl -I --http2 https://cdn.example.com
- 检查Nginx配置生效
# 查看最终生效配置
nginx -T | sed -n '/server_name example.com/,/}/p'
5. 关键配置示例(完整可执行)#
- 文件:
/etc/nginx/conf.d/site.conf
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/nginx/ssl/site.crt;
ssl_certificate_key /etc/nginx/ssl/site.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1d;
ssl_session_tickets on;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 1.1.1.1 valid=300s;
http2_max_concurrent_streams 256;
http2_recv_timeout 30s;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
}
# 观测状态
location /nginx_status {
stub_status;
allow 127.0.0.1;
deny all;
}
}
# 检查配置并重载
nginx -t && systemctl reload nginx
6. 性能瓶颈与优化点(含验证方法)#
- 握手成本过高
bash # 通过ab对比会话复用前后耗时 ab -n 1000 -c 50 https://example.com/ - 开启会话复用:
ssl_session_cache shared:SSL:50m; - 加密算法过重
bash # 输出支持的密码套件,选择ECDHE优先 openssl ciphers -v 'ECDHE+AESGCM:!aNULL:!MD5' - HTTP/2并发流过多导致队头阻塞
- 调整
http2_max_concurrent_streams,结合上游处理能力进行压测验证。 - OCSP响应慢
- 启用
ssl_stapling并确认resolver可用。
7. 兼容性排查要点(含对照检查)#
- TLS版本兼容
bash # 仅测试TLS1.2 openssl s_client -connect example.com:443 -tls1_2 </dev/null | grep "Protocol" # 仅测试TLS1.3 openssl s_client -connect example.com:443 -tls1_3 </dev/null | grep "Protocol" - SNI支持
bash # 不带SNI访问(观察是否返回默认站点证书) openssl s_client -connect example.com:443 </dev/null | openssl x509 -noout -subject - 代理链HTTP/2降级
- 比较
Alt-Svc、via、server响应头,确认链路位置。
8. 典型问题与处理建议(含排错命令)#
- 握手失败/证书链缺失
bash # 输出完整证书链并确认包含中间证书 openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null - 处理:合并证书链或使用全链证书文件(fullchain)。
- HTTP/2协商失败
bash # 检查编译支持 nginx -V 2>&1 | grep http_v2 - 处理:升级Nginx或重新编译;确保
listen 443 ssl http2;写在正确的 server 块。 - CPU负载过高
- 处理:启用会话复用/票据,优先 ECDHE 套件,评估硬件加速或升级实例规格。
9. 练习与自检清单#
- 使用
curl -Iv验证 ALPN 协商是否为h2,记录结果。 - 用
openssl s_client获取证书链,检查有效期与域名是否一致。 - 调整
http2_max_concurrent_streams为 128/256,对比压测结果。 - 关闭/开启
ssl_session_tickets,对比握手耗时。
自检清单
- 证书链完整且未过期
- TLS1.2/1.3 协商成功
- HTTP/2 协商成功
- 关键指标:握手耗时、HTTP/2错误码、QPS、连接数与CPU 可观测