这类问题我又碰上了一次。一台 8 核 16G 的 CentOS 7.9 上用 nginx 反代四个后端,ss -s 显示 TIME_WAIT 两万四千多,后端应用日志里大量连接被重置,接口偶发 502。
第一反应是「Connection 头没清掉,后端回的 close 让连接无法保持」,验证下来不成立。
排查方向其实有限,先把可能性排一排。upstream 没配 keepalive,每个请求都新建一条 TCP 连接,关闭后进入 TIME_WAIT,两万多个端口占用就是这么攒出来的;proxy_http_version 还是 1.0,即便配了 keepalive 也不会复用连接;本地端口范围太小,TIME_WAIT 堆积之后新连接直接失败。
第一件事是看 TIME_WAIT 的规模与分布
ss -s && ss -tan state time-wait | wc -l
接着在 upstream 里开启长连接池
printf 'upstream app { server 10.0.0.11:8080; keepalive 64; }\n' > /etc/nginx/conf.d/up.conf && nginx -t
补齐 HTTP 版本与连接头设置
printf 'proxy_http_version 1.1;\nproxy_set_header Connection "";\n' > /etc/nginx/conf.d/keep.conf && nginx -s reload
剩下的就是观察连接数与后端状态
ss -tan state established '( dport = :8080 )' | wc -l
怎么算真的好了,看的是同一批现象。TIME_WAIT 数量降到两千以内,established 连接稳定在几十条,后端不再出现连接被重置,接口 502 消失。
容易忽略的是,keepalive 的数字是每个 worker 的空闲连接上限,不是总数;只加 keepalive 不改 HTTP 版本等于白配,三处设置必须一起改。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。
