nginx keepalive在高延迟弱网下连接保持率的测试核心是验证空闲连接是否被客户端或中间网络静默断开而nginx未感知,需用tc模拟弱网、ss监控内核keepalive计时器、双向日志比对及openssl直探tcp层行为。

测试 Nginx 的 keepalive 在高延迟弱网下的长效连接保持率,核心不是看“连得上”,而是验证“空闲时是否真被客户端或中间网络提前断开,而 Nginx 还在傻等”。关键在于模拟真实弱网行为,并观测连接生命周期的两端状态。
用 tc 模拟弱网并抓包观察连接存活行为
在服务端或客户端(推荐用测试机或容器)部署 tc 注入高延迟、丢包和乱序:
- 典型弱网配置:延迟 300ms ±50ms,丢包率 2%–5%,带宽限 1Mbps(模拟 4G 边缘或地铁出站场景)
-
执行命令示例:
tc qdisc add dev eth0 root netem delay 300ms 50ms distribution normal loss 3% - 随后用
curl -v --http1.1 -H "Connection: keep-alive" https://your-api.com/ping发起首个请求,记录响应头中的Keep-Alive: timeout=XX - 等待超时值减去 10 秒后,再发第二个请求——若返回
Connection: keep-alive且无 TLS 重握手日志,则说明连接复用成功
用 ss + timestamp 监控连接实际存活时长
在 Nginx 服务器上持续采样,确认连接是否按预期关闭:
- 运行
watch -n 1 'ss -tn state established "( sport = :443 )" | awk "{print \$6}" | sort | uniq -c' - 重点关注
timer:(keepalive,XXsec)字段:它显示内核为该连接设置的 keepalive 计时器剩余秒数(非 Nginx 配置值) - 若该值长期卡在 20–30 秒不再递减,说明连接已被对端静默关闭,但 Nginx 尚未感知(常见于 NAT 超时或 iOS 后台回收)
- 对比
keepalive_timeout设置值与实际计时器衰减节奏,可判断是否匹配终端真实保活窗口
结合客户端日志与 Nginx access_log 做双向比对
单边日志不可靠,必须交叉验证:
- 在 Nginx
log_format中加入$connection_requests和$upstream_http_connection,观察同一 TCP 连接是否承载多个请求 - 客户端侧开启 OkHttp 或 NSURLSession 的网络调试日志(如 Android
OkHttpClient.Builder().connectTimeout(30, SECONDS).pingInterval(30, SECONDS)),记录 socket 复用 ID 及 close 原因 - 筛选出
request_time > 1s且connection_requests == 1的请求——大概率是新建连接,说明前一个 keepalive 已失效
用 openssl s_client 手动触发并测量空闲期
绕过 HTTP 客户端逻辑,直探 TCP 层行为:
- 执行
openssl s_client -connect your-domain.com:443 -tls1_3 -quiet,输入GET /ping HTTP/1.1\r\nHost: your-domain.com\r\nConnection: keep-alive\r\n\r\n - 发送完后不关闭连接,用
date +%s记录起始时间,等待设定的keepalive_timeout时间后,再发一次 GET - 若收到响应且无
SSL routines:ssl3_read_bytes:ssl handshake failure,说明连接仍有效;若报错或超时,则定位到具体失效时刻











