Linux服务器ESTABLISHED连接过多怎么办?空闲连接、TCP Keepalive与连接泄漏排查教程
本内容发表于:2026-09-04 15:07:17
浏览量
1048

Linux服务器ESTABLISHED连接过多排查示意图

在 Linux 服务器上执行 ss -ant,如果看到成百上千甚至更多的 ESTABLISHED 连接,第一反应往往是“连接泄漏”或“服务器快撑不住了”。但 ESTABLISHED 只表示 TCP 三次握手已经完成,双方仍维持连接状态,并不代表连接此刻一定在传输业务数据,也不能单凭数量判断故障。

WebSocket、HTTP/2、数据库连接池、消息队列消费者和反向代理都可能长期保持连接。真正需要回答的是:这些连接属于哪个进程、集中在哪个端口、是否持续收发数据、空闲多久,以及数量是否正在失控增长。

一、ESTABLISHED 连接多,哪些情况可能是正常的?

以下业务本身就会保留大量已建立连接:

  • WebSocket、在线客服、实时推送和长轮询;

  • HTTP/2 或 HTTP/3 网关后的持续会话;

  • Nginx、HAProxy、应用服务器之间的 Keep-Alive 连接;

  • 数据库、Redis、消息队列等连接池;

  • 微服务之间的 RPC 长连接;

  • 高并发下载、视频传输或大文件上传。

如果连接数随在线用户或请求量同步变化,吞吐、延迟、错误率和文件描述符都处于正常范围,这些连接通常是业务容量的一部分。相反,如果请求量已经下降,连接数仍单向增长,或者某个进程的文件描述符不断逼近上限,就要重点排查空闲连接和连接泄漏。

二、先确认连接规模和变化趋势

查看 TCP 状态汇总:

ss -s
cat /proc/net/sockstat

只查看已建立连接:

ss -ant state established

不要只记录一个瞬时数字。建议每隔一分钟采样一次,并同时记录业务 QPS、在线用户、CPU、内存、网络吞吐和错误率。若连接数持续增长而业务量没有同步增长,风险更高。

三、找出连接集中在哪个端口、IP 和进程

1. 按本地端口聚合

ss -ant state established | awk 'NR>1 {split($4,a,":"); print a[length(a)]}' | sort | uniq -c | sort -nr | head

这能帮助判断连接主要来自 Web 服务端口、数据库端口,还是某个内部应用端口。IPv6 地址包含多个冒号,生产环境可结合实际输出使用更可靠的脚本或结构化监控处理。

2. 按远端地址聚合

ss -ant state established | awk 'NR>1 {print $5}' | sed 's/:[^:]*$//' | sort | uniq -c | sort -nr | head

如果连接高度集中于少数来源,应结合负载均衡、NAT、代理出口和真实客户端 IP 判断。看到同一个地址不一定意味着单个用户,也可能是上游代理或 NAT 网关。

3. 关联到具体进程

sudo ss -antp state established
sudo lsof -nP -iTCP -sTCP:ESTABLISHED

重点观察 PID、程序名、本地端口和对端地址。若同一进程的连接数不断增长,可进一步检查线程池、连接池、超时配置和异常路径是否正确释放套接字。

四、判断连接是活跃、空闲还是阻塞

ESTABLISHED 状态本身无法说明是否在传输数据。可以查看更详细的套接字信息:

sudo ss -iantop state established

结合发送队列、接收队列、重传、RTT、拥塞窗口和计时器判断。长期存在较大的 Send-Q 可能表示客户端读取过慢、网络拥塞或对端处理不及时;较大的 Recv-Q 可能表示应用没有及时读取已经到达的数据。

需要确认实际报文时,可在明确端口和范围后短时间抓包:

sudo tcpdump -ni any tcp port 443

抓包可能包含敏感信息,也会增加系统负担。生产环境应限制接口、端口、主机和抓取时长,并按照内部安全规范处理文件。

五、检查文件描述符是否接近上限

每个 TCP 套接字通常会占用文件描述符。连接很多时,应同时检查系统和进程限制:

ulimit -n
cat /proc/<PID>/limits
ls /proc/<PID>/fd | wc -l
cat /proc/sys/fs/file-nr

如果进程已接近 Max open files,新连接、日志文件或其他文件操作都可能失败。提高上限只能增加容量,不能修复连接没有释放的应用缺陷。调整前应先确认连接增长原因、内存预算和服务管理器中的限制配置。

六、TCP Keepalive 为什么没有自动清理所有空闲连接?

Linux 提供以下常用参数:

sysctl net.ipv4.tcp_keepalive_time
sysctl net.ipv4.tcp_keepalive_intvl
sysctl net.ipv4.tcp_keepalive_probes
  • tcp_keepalive_time:连接空闲多久后开始发送探测;

  • tcp_keepalive_intvl:探测之间的间隔;

  • tcp_keepalive_probes:认定连接失效前最多发送多少次探测。

需要特别注意:这些内核参数只会影响已经启用 SO_KEEPALIVE 的套接字。应用没有为连接开启 TCP Keepalive,仅修改 sysctl 并不会让所有已建立连接自动获得探测机制。

应用层心跳与 TCP Keepalive 也不是同一件事。应用层心跳能够验证业务协议和应用进程是否仍在响应,并可携带会话信息;TCP Keepalive 主要用于识别连接路径或对端主机是否已经失效。WebSocket、数据库驱动和 RPC 框架通常还需要配置各自的 ping、心跳或空闲超时。

七、常见根因与对应处理

正常长连接容量不足

如果连接与活跃用户一致,应按容量问题处理:核对进程文件描述符、内存占用、负载均衡连接能力和连接池上限,并通过扩容或分片分担连接。

应用连接泄漏

检查异常、超时和取消请求路径是否都会执行关闭操作。数据库或 HTTP 客户端连接池要设置合理的最大连接数、最大空闲连接数、空闲回收时间和连接生命周期。修复应落在应用代码或连接池配置上,而不是依赖系统强制清理。

慢客户端或网络质量差

结合 Send-Q、重传和应用响应时间确认。可以设置合理的读写超时、请求体限制和并发限制,但不要为了快速降低连接数而盲目调低超时,以免误断正常的大文件传输或弱网用户。

中间设备空闲超时不一致

负载均衡、NAT、防火墙和代理可能有不同的空闲超时。应用层心跳间隔通常应短于路径中最短的空闲超时,并留出安全余量。具体数值要根据当前设备文档、业务特性和实际网络测试确定。

连接跟踪表压力

使用 Netfilter 的服务器或网关还可检查:

sudo conntrack -S
sysctl net.netfilter.nf_conntrack_count
sysctl net.netfilter.nf_conntrack_max

如果系统没有安装 conntrack 工具,或者主机不承担相关网络角色,命令可能不可用。连接跟踪表与应用套接字不是同一个维度,需要结合网络拓扑分析。

八、推荐的排查顺序

  1. 确认连接总量、增长速度和出现时间;

  2. 对照 QPS、在线用户、延迟、错误率和网络吞吐;

  3. 按本地端口和远端地址聚合;

  4. 关联 PID,找出主要进程和服务;

  5. 检查 Send-Q、Recv-Q、重传和套接字计时器;

  6. 检查进程文件描述符及连接池上限;

  7. 核对应用超时、心跳、SO_KEEPALIVE 与内核参数;

  8. 核对负载均衡、NAT、防火墙的空闲超时;

  9. 必要时进行受控抓包或应用级追踪。

九、修改参数前如何降低风险?

不要直接在全部服务器上修改 Keepalive、连接池或超时。先保存当前参数和监控基线,在少量实例上灰度变更,持续观察连接数、重连率、错误率、P95/P99 延迟、CPU、内存和文件描述符。准备可执行的回滚值,并确认配置能在重启后按预期生效。

如果降低空闲超时后连接数下降,却同时出现重连激增、登录掉线或数据库连接抖动,这通常不是成功修复,而是把压力转移到了握手和重建连接阶段。

十、修复后如何验证?

  • 连接数是否随真实业务量稳定变化,不再无界增长;

  • 进程文件描述符是否回到安全水位;

  • 连接池等待时间、超时和拒绝数量是否下降;

  • 重连率、握手量和错误率是否没有异常上升;

  • 弱网客户端、长任务和大文件传输是否仍然正常;

  • 重启或滚动发布后配置是否仍然有效。

常见问题

ESTABLISHED 连接多就是被攻击了吗?

不是。正常长连接和高并发业务也会产生大量已建立连接。攻击判断需要结合来源分布、请求行为、带宽、错误率、认证日志和业务基线。

可以直接 kill 掉这些连接吗?

不建议把批量断开作为常规修复。它会中断正常用户,并可能引发集中重连。应先定位进程、业务类型和根因;紧急处置也要控制范围并准备回滚。

把 tcp_keepalive_time 调得很小可以吗?

数值过小会增加探测流量和误判风险,而且应用未启用 SO_KEEPALIVE 时不会按预期生效。应根据业务空闲周期和中间设备超时灰度调整。

为什么服务重启后连接数马上又上来了?

如果连接来自正常客户端或自动重连机制,重启只会暂时清空状态。若根因是容量不足、泄漏、超时不匹配或客户端行为,连接仍会重新建立。

结论

Linux 服务器出现大量 ESTABLISHED 连接时,正确做法不是先调内核参数,而是先把连接与端口、来源、进程、业务流量和文件描述符对应起来。确认是正常长连接后做容量规划;确认是空闲连接、泄漏或超时不匹配后,再分别从应用、连接池、Keepalive 和网络设备配置入手。任何全局参数变更都应有基线、灰度、监控和回滚。

参考资料

  1. RFC 9293:Transmission Control Protocol (TCP),核查日期:2026-09-04

  2. Linux Kernel Documentation:IP Sysctl,核查日期:2026-09-04

  3. Linux man-pages:ss(8),核查日期:2026-09-04

  4. Linux man-pages:tcp(7),核查日期:2026-09-04