Nginx作CDN时HTTP2、内容下载及TTFB过慢问题求助
排查Nginx CDN HTTP2/下载/TTFB缓慢问题的实操步骤
先给你打个底:你的服务器硬件配置完全够打,负载和内存空闲都很健康,所以问题肯定不在硬件层面,大概率是配置、网络链路或者系统参数优化不到位导致的。咱们一步步来排查:
1. 先排除网络链路的锅
服务器在Hetzner,先确认网络本身没毛病:
- 用
mtr或者traceroute测试你本地到服务器的链路,看看有没有丢包或高延迟的跳点。执行命令:
重点看中间节点的丢包率,如果某一跳丢包超过5%,那可能是运营商或中转节点的问题。mtr --report your-server-ip - 验证服务器带宽是否真能跑满1Gbps,用
iperf3做双向测试:
如果测速远低于1Gbps,去Hetzner后台看看有没有网络告警,或者联系他们确认带宽是否正常分配。# 服务器端启动服务 iperf3 -s # 本地客户端测试(开10个并发流跑60秒) iperf3 -c your-server-ip -P 10 -t 60
2. 检查HTTP2配置是否踩坑
Nginx 1.13.8支持HTTP2,但配置细节很影响性能:
- 确保
listen指令明确开启了http2,比如:
别漏了listen 443 ssl http2;http2参数! - 优化SSL配置,因为HTTP2依赖SSL,烂的SSL配置会直接拖垮速度:
- 启用会话复用,减少重复握手的开销:
ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; - 用高效的加密套件,避开老旧的弱加密:
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers off; - 开启OCSP Stapling,让客户端不用去查证书吊销列表:
ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s;
- 启用会话复用,减少重复握手的开销:
- 加上TCP优化参数,对HTTP2的传输很重要:
tcp_nopush on; tcp_nodelay on;
3. 检查CDN缓存是否真的生效
既然是CDN,缓存没起作用会导致频繁回源,直接拉高TTFB:
- 看stub_status里的
hit和miss比例,如果miss率很高,说明缓存规则没配置对。比如静态资源(js、css、图片)要设置足够长的缓存时间,比如:location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ { expires 30d; add_header Cache-Control "public, immutable"; proxy_cache_valid 200 30d; } - 检查缓存目录的权限,确保Nginx进程(一般是
www-data)有读写权限:ls -ld /path/to/your/nginx/cache - 开启文件缓存,优化静态文件的读取性能:
open_file_cache max=10000 inactive=20s; open_file_cache_valid 30s; open_file_cache_min_uses 2; open_file_cache_errors on;
4. 系统网络参数优化(Ubuntu 16.04默认太保守)
Ubuntu 16.04的默认网络参数没针对高带宽优化,改一下/etc/sysctl.conf:
# 增大TCP缓冲区 net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 # 增大监听队列 net.core.somaxconn = 65535 # 优化TCP连接复用 net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_fin_timeout = 30 net.ipv4.tcp_max_syn_backlog = 65535
然后执行sysctl -p让参数生效。
5. 用日志和stub_status找线索
- 看Nginx的access.log,找慢请求:
这个命令会把请求耗时排序,看看有没有大量超过1秒的请求。awk '{print $NF}' /var/log/nginx/access.log | sort -n | uniq -c | sort -rn | head -20 - 分析stub_status的输出:
- 如果
server accepts handled requests里的accepts和handled差距大,说明有连接被拒绝,要调大监听队列。 - 如果
Waiting数很高,说明keepalive超时设置太长,导致大量空闲连接占用资源,可以把keepalive_timeout降到60秒左右。
- 如果
6. 直接测试HTTP2 vs HTTP1.1的性能
用curl分别测HTTP2和HTTP1.1的TTFB和下载速度,对比差异:
# HTTP2测试 curl -s -w '\nTTFB: %{time_starttransfer}s\nTotal time: %{time_total}s\nSpeed: %{speed_download} bytes/sec\n' -o /dev/null https://your-domain.com/large-file.test # HTTP1.1测试 curl -s --http1.1 -w '\nTTFB: %{time_starttransfer}s\nTotal time: %{time_total}s\nSpeed: %{speed_download} bytes/sec\n' -o /dev/null https://your-domain.com/large-file.test
如果HTTP2比HTTP1.1慢很多,那大概率是HTTP2的配置有问题。
要是以上步骤都没解决问题,麻烦提供这些信息方便进一步排查:
- 去掉敏感信息后的完整
nginx.conf - stub_status的具体输出内容
- 你测试用的公开文件路径(如果可以的话)
- 你测试的地理位置(跨区域网络延迟也会有影响)
内容的提问来源于stack exchange,提问作者apsuva




