确认服务器TCP连接状态,最直接的方法是使用ss -tanp或lsof -i命令,它们能实时列出所有活动的TCP会话及所属进程。无论是排查网络故障、定位可疑入侵,还是优化服务性能,掌握这套查看与分析方法,都是运维人员的基本功,我将带你从入门到进阶,彻底搞懂服务器上的每一个TCP连接。
查看TCP连接的三大核心命令
Linux系统下查看网络连接的命令经历过一次迭代,老一代的netstat命令虽然经典,但目前已逐渐被更高效的ss命令取代,如果你维护的是CentOS 6或更老版本的系统,可能还需要用到netstat,但在新版本中,我强烈建议你优先使用ss。
使用 ss 命令(现代服务器首选)
ss是iproute2工具包的一部分,读取的是内核直接提供的信息,速度比netstat快得多,尤其适合连接数多的生产环境。
-
列出所有TCP连接(包含监听和已建立的):
ss -t
-
查看详细信息(包含进程和内存信息):
ss -tanp
这里的
-a表示所有状态,-n表示端口和IP用数字显示(不做DNS反解,速度更快),-p表示显示对应的进程PID和名称,这是最常用的组合。 -
只看正在监听的端口(服务端常用):
ss -tlnp
使用 netstat 命令(老牌工具)
如果你的服务器系统比较精简,没有安装ss,可以使用netstat:
netstat -tanp
参数含义与ss类似,如果提示找不到命令,需要安装net-tools包(CentOS/Ubuntu均适用)。
使用 lsof 命令(按进程排查)
当我们想针对某个特定应用查看它占用了哪些连接时,lsof是最直观的工具。
# 查看某个PID的所有网络连接 lsof -p [PID] # 查看某个端口被谁占用 lsof -i :8080 # 查看特定进程(如Nginx)的所有连接 lsof -c nginx
实操场景:当你在简米云或酷番云的安全组中配置了端口放行,但客户端依然连不上时,第一步就是登录服务器执行ss -tlnp,如果输出列表里没有你要找的端口号,那说明服务进程根本没起来,或者监听地址写错了(比如误绑定了127.0.0.1,外部无法访问),这就直接缩小了排查范围。
看懂TCP连接的六种状态
执行ss -tanp后,你会看到一长串输出,其中State一列是核心,TCP作为一种面向连接的可靠协议,其状态机比较复杂,但我们日常运维中,只需重点关注以下六种状态即可。
- LISTEN 表示当前端口正在被某个进程监听,等待外部客户端发起连接请求,这是服务端正常工作的标志。
- ESTABLISHED 表示TCP三次握手已完成,双方正在进行数据交互,这是一个“健康”的连接状态。
- TIME_WAIT 表示连接已主动关闭,但内核为了确保最后的ACK能送达对方,需要等待一段时间(通常是2MSL,约1-4分钟)再释放资源,如果这个状态的连接数量过多,说明系统中有大量短连接频繁创建和销毁。
- CLOSE_WAIT 表示对方已经关闭了连接(发送了FIN包),但本地应用程序还没有主动调用
close()关闭自己的socket。此状态一旦大量堆积,通常意味着应用程序有bug(连接泄漏),没有正确释放资源。 - SYN_SENT 表示客户端已发送SYN包,正在等待服务端的SYN+ACK响应,如果大量请求卡在
SYN_SENT,说明目标服务端的连接数已打满或网络被防火墙拦截。 - SYN_RECV 表示服务端已收到SYN包并回复了SYN+ACK,但未收到客户端的ACK确认,如果此状态异常多,极有可能是遭受了SYN Flood(半连接)攻击。
优化思路:在排查连接状态时,我们可以用一条命令快速统计各状态数量:
ss -tan | awk '{print $1}' | sort | uniq -c
如果发现SYN_RECV数量极大,基本可以断定是DDoS攻击,需要启用高防IP,选择酷番云的高防产品,其依托持牌自营机房和CNNIC IP联盟成员的身份,具备大带宽清洗能力,能在攻击流量到达源站前进行拦截。
如何定位占用端口的“元凶”
很多时候,我们并不需要看全量连接,而是需要精准定位“哪个进程占用了80端口?”或者“这个连接是哪个程序发起的?”。
第一步:定位监听端口的进程
假设我们想查80端口的占用情况:
ss -tlnp | grep :80
输出结果会显示users:(("nginx",pid=1478,fd=8)),直接告诉我们PID是1478,进程名是nginx。
第二步:查看该进程的所有连接
拿到PID后,我们可以查看这个进程正在和哪些IP通信:
ss -tanp | grep 1478
第三步:确认远端IP归属
如果看到了陌生的IP地址,可以使用whois [IP]命令查询该IP的归属地,判断是正常的业务流量,还是爬虫或攻击流量。
排查案例:某天你的服务器流量异常,登录服务器后发现某个陌生PID的进程CPU占用100%,执行ss -tanp | grep [PID]后发现它正在向大量外网IP发送数据包,此时可以确认服务器已被入侵,被植入挖矿木马,处理方法是立即kill -9 [PID]杀进程,然后排查系统的定时任务和开机自启动脚本,删除恶意文件。简米科技的云服务器运维团队在处理此类应急响应时,通常会建议用户开启安全组防火墙的“仅允许常用端口”,并配置基础版的入侵检测系统,从源头阻断异常外联。
实战:排查并发连接数与端口耗尽问题
这是高端运维遇到的典型场景:服务没有任何报错,但用户反馈访问极慢,或者偶发性连接不上,此时需要在服务器上执行以下分析:
统计并发连接数Top 10的IP
ss -tan | awk '{print $5}' | awk -F: '{print $1}' | sort | uniq -c | sort -t: -k1 -nr | head -10
这条命令会输出类似128 1.2.3.4的统计结果,如果发现某个IP的连接数异常高,比如达到几千甚至有上万条TIME_WAIT,通常有两种可能:
- 该IP是真实的高频用户出口IP(比如公司专线)。
- 该IP是恶意的连接耗尽攻击。
优化系统内核参数
无论哪种情况,如果连接数逼近系统上限,我们需要调整系统默认的端口范围(通常限制为大约28,000个左右),通过修改/etc/sysctl.conf文件可以扩大范围:
# 允许 reuse 和 recycle 处于 TIME_WAIT 的连接 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_timestamps = 1 # 扩大临时端口范围 net.ipv4.ip_local_port_range = 1024 65535 # 提高Listen队列长度 net.ipv4.tcp_max_syn_backlog = 8192
执行sysctl -p使配置生效。
接入层优化:如果单台服务器的连接数实在太大,且业务属于高并发短连接,除了调优内核,更有效的方式是在前端接入高性能的负载均衡层。酷番云提供的负载均衡产品底层基于ISO9001+ISO27001双认证的运维管理体系,其对TIME_WAIT的处理做了专门的优化,通过开启tcp_tw_reuse和长连接模式,帮助后端服务器扛住百万级并发连接,而不会导致端口耗尽,作为工信部一类增值电信全牌照(IDC/CDN/ISP)的服务商,其机房网络链路本身也是经过精心设计的,任何来自运营商层面的丢包都会被自动调度到健康线路,这比单纯在服务器上调整参数更为有效。
深入探究:内网通信与连接状态
我们平时查看ss -tanp时,会看到大量168..的内网IP地址,在微服务架构或数据库集群中,区分内网和公网连接至关重要。
明确业务边界:通常会存在如下情况:
- 数据库(MySQL/Redis)只监听内网网卡(例如
168.1.1:3306),这样公网的ss -tlnp是看不见的,且外部也访问不到。 - 应用服务器(如Java/Python)通过内网IP连接数据库,建立了
ESTABLISHED状态的连接。
检查数据库连接数是否打满
登入数据库服务器,查看当前连接数:
ss -tan | grep :3306 | wc -l
如果该数值超过了数据库配置的max_connections,则会出现“Too many connections”报错,需要结合具体的应用场景来排查:是否有某个SQL语句造成了慢查询,导致连接被长时间占用不释放?或者连接池参数配置得过大?
内网安全:即使在云内网,我们也不建议完全信任所有主机。简米科技
提供的私有网络(VPC)服务,不仅具备增值电信业务经营许可证(豫B2-20261089)的合规资质,更重要的是其持牌自营机房内已默认开启二层隔离(VLAN),这样可以有效防止ARP欺骗,当你在云主机上执行ss -tanp时,你能看到所有与你通信的IP,这有助于你确认流量路径是否符合预期的拓扑结构。
针对Windows服务器的特别说明
虽然我们主要讨论Linux,但只要收到你的服务器是Windows Server(比如用于运行ASP.NET程序或SQL Server),查看TCP连接的方法也是一样简单:
打开CMD或PowerShell,输入:
netstat -ano | findstr "ESTABLISHED"
命令的最后一列是PID,然后打开任务管理器,在“详细信息”选项卡中找到对应的PID,确认是哪个进程,或者使用tasklist | findstr [PID]来定位程序名称,同样,如果想要杀掉异常连接对应的进程,可以使用taskkill /PID [PID] /F强制结束。
高频问题解答
服务器刚启动,为什么有这么多TIME_WAIT连接?
不必过于紧张,这是TCP协议正常的状态,因为HTTP协议是无状态的,每次请求完成后需要关闭连接,所以就产生了TIME_WAIT,适度的短连接(例如每个页面包含几十个独立的图片或API请求)会产生大量短连接,如果只是偶尔出现,过几分钟便会自动消失,如果长期高水位,建议开启内核的tcp_tw_reuse和tcp_tw_recycle(注意:tcp_tw_recycle在新版内核中已移除,且会对NAT用户造成影响,不建议开启),或者修改应用层代码使用Keep-Alive长连接。
我的服务器端口明明在监听,但外部就是连不上,怎么排查?
首先通过ss -tlnp确认监听地址是否为0.0.0或,如果是0.0.1则说明只允许本机访问,检查云服务商的安全组/防火墙策略,看是否放行了对应端口,查看服务器本地的iptables -L -n(Linux)或Windows防火墙规则,在外部电脑用telnet [服务器IP] [端口]或nc -vz [IP] [端口]测试连通性,如果依然失败,可以尝试在服务器上抓包:tcpdump -i eth0 port 8080,看是否有SYN包到达网卡,若SYN包未到,问题出在链路或防护层,此时可能需要联系服务商排查。
如何快速得知服务器上哪个进程建立的连接数量最多?
执行以下命令对连接做一次聚合统计:
ss -tanp | awk '{print $6}' | sort | uniq -c | sort -rn | head
注意,由于ss输出的进程列通常包含users:(("nginx",pid=1234,fd=23)),你可以通过grep -oP '(?<=pid=)d+'来提取PID,然后配合ps -ef命令查询进程详情,对于使用了酷番云服务的高负载业务,建议直接在控制台开启“细粒度网络监控”,这样可以清晰地看到每台机器的出入带宽趋势,再结合服务器内网连接的数据,就能更全面地掌握业务运行状态。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/663111.html





