端口耗尽主因常是TIME_WAIT堆积、短连接风暴或隐藏进程占端口,而非ip_local_port_range过小;应使用ss -tulnp、lsof、/proc/net/{tcp,tcp6}精准排查,启用tcp_tw_reuse、慎调fin_timeout,并检查systemd用户实例、残留容器及内核socket异常。

端口耗尽问题不一定是 net.ipv4.ip_local_port_range 设置不够大,更可能是系统中存在大量未释放的 TIME_WAIT 连接、短连接风暴、或被忽略的后台进程持续占着端口(尤其是非 root 进程绑定固定端口后长期不退出)。
检查真实端口占用情况,别只看 netstat -an
默认 netstat 或 ss 不显示 PID 和进程名,容易漏掉“隐身”进程:
- 用
ss -tulnp(需 root 权限)查所有监听和已建立连接的进程,重点关注:*:*:*:*类型的监听和大量TIME-WAIT状态 - 用
lsof -i -P -n | grep ':查特定端口归属,比如怀疑某端口被霸占时精准定位' - 用
cat /proc/net/{tcp,tcp6}手动解析(十六进制端口号需转换),适合排查内核级或容器逃逸类异常进程
TIME_WAIT 不是敌人,但配置不当会雪上加霜
调大本地端口范围只是治标。Linux 默认 net.ipv4.tcp_fin_timeout = 60,而 TIME_WAIT 持续 2×MSL(通常 60 秒),若每秒新建 1000+ 短连接,60 秒内就可能占满 65535 个端口:
- 启用端口重用:
net.ipv4.tcp_tw_reuse = 1(客户端主动发起连接时可复用处于 TIME_WAIT 的端口) - 谨慎调低超时:
net.ipv4.tcp_fin_timeout = 30(仅对非 NAT 环境安全;NAT 下可能丢包) - 禁用回收(不推荐):
net.ipv4.tcp_tw_recycle = 0(已在 4.12+ 内核移除,且在 NAT 场景下会导致连接失败)
揪出“隐藏进程”:systemd、容器、孤儿线程
真正耗尽端口的常不是前台服务,而是以下几类:
-
systemd 用户实例残留:执行
loginctl list-users+systemctl --user list-units --state=running,查看是否有崩溃后未清理的用户级服务占着 8080/9000 等常用端口 -
容器未彻底退出:运行
docker ps -a和podman ps -a,检查 Exited 容器是否仍持有网络命名空间(用nsenter -n -t进入其 netns 查看)ss -tuln -
僵尸 socket 或内核模块:极少数情况下,驱动或 eBPF 程序创建的 socket 未正确释放,可通过
cat /proc/net/sockstat对比sockets: used和tcp:行数值是否严重失衡
验证与收尾建议
改完参数后别直接重启,先验证:
- 确认生效:
sysctl net.ipv4.ip_local_port_range和ss -s中 “TCP: time wait” 数量趋势 - 压力测试对比:
ab -n 10000 -c 100 http://127.0.0.1:8080/前后分别记录netstat -an | grep :8080 | wc -l - 设为持久:把调整项写入
/etc/sysctl.d/99-custom.conf,避免重启失效










