这个命令是干啥的
这其实两个命令,但做的事一样:看网络连接状态、端口监听情况。netstat 是老牌工具,我入行的时候就在用,但随着服务器连接数越来越大(尤其大并发场景),netstat跑一次要好几秒,还经常卡住。ss 是新一代替代品,直接从内核的socket信息读数据,速度快一个数量级。
现在的新系统基本都推荐用 ss 了。有些发行版甚至默认不装net-tools包(netstat就在里面),得自己装。但我两边都讲,因为你保不齐会遇到只有netstat的环境。
netstat 安装:
# Ubuntu/Debian
apt install net-tools
# CentOS/RHEL
yum install net-tools
基本用法(3分钟上手)
用ss查看所有监听的端口
排查端口占用是最常用的场景。
# 查看所有正在监听的TCP端口(含进程信息)
ss -tlnp
参数拆解:
- -t:只显示TCP连接
- -l:只显示监听中的(LISTEN状态)
- -n:不解析主机名和端口名,直接显示IP和数字端口(快很多)
- -p:显示占用端口的进程信息
输出示例:
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=12345,fd=6))
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=6789,fd=3))
一眼就能看出80端口是nginx在监听,22端口是sshd在监听。
netstat版
# netstat查看监听端口
netstat -tlnp
参数差不多,就是多了个 -tlnp。但netstat跑得明显慢,尤其服务器上连接上万的时候。
查看所有连接(包括非监听状态)
# 查看所有TCP连接
ss -tan
# 查看所有UDP连接
ss -uan
进阶骚操作
ss -s 一键统计
这是我最喜欢的功能,一条命令看全系统的连接概览:
# 查看系统级连接统计
ss -s
输出:
Total: 1234 (kernel 2345)
TCP: 456 (established 234, closed 123, orphaned 1, synrecv 0, timewait 89, ...)
一眼看到有多少ESTABLISHED连接、多少TIME_WAIT。如果TIME_WAIT数量异常高,说明连接回收有问题。
按状态过滤连接
# 只看ESTABLISHED状态的连接
ss state established
# 只看LISTEN状态的
ss state listening
# 只看TIME_WAIT的
ss state time-wait
# 排除特定状态
ss state all exclude time-wait
这个功能 netstat 没有,ss 原生支持。
查看连接数统计
# 统计每个状态的连接数
ss -tan | awk '{print $1}' | sort | uniq -c | sort -rn
# 统计每个远程IP的连接数(定位哪个客户端连接最多)
ss -tan | grep ESTAB | awk '{print $5}' | awk -F: '{print $1}' | sort | uniq -c | sort -rn | head -10
有次线上服务被爬虫狂刷,我用第二行命令一看,某个IP有2000+个连接,直接iptables封掉就解决了。
查看哪个进程占用了某端口
# 查80端口被哪个进程占用了
ss -tlnp | grep :80
# netstat版
netstat -tlnp | grep :80
输出结果里能看到进程名和PID。如果端口被占用了但不知道是谁,这招最管用。
查看本地端口和远程端口
# 只看特定端口的连接(本地或远程都可以)
ss -tan | grep :8080
避坑指南
坑1:netstat和ss统计结果不一致
有次我用netstat统计连接数,和ss对不上。后来发现netstat默认不显示所有socket,而ss从内核直接读,更准确。而且netstat在连接数多的时候会丢数据(读太快导致/proc/net/tcp不完整)。
结论:以ss为准。
坑2:服务器连接数上万时,netstat会卡
这个我亲身经历过。一台连接数3万左右的服务器,执行 netstat -an,等了快10秒还没出结果。换成 ss -tan,不到1秒就出来了。原理是netstat读/proc目录下的文件,而ss直接调用内核的netlink接口。
坑3:TIME_WAIT过多怎么办
TIME_WAIT是TCP四次挥手的正常状态,但数量太多会占用端口资源。
先用ss看看实际情况:
# 统计TIME_WAIT数量
ss -tan | grep TIME-WAIT | wc -l
如果数量超过几万,可以调整内核参数:
# 编辑/etc/sysctl.conf或/etc/sysctl.d/99-tcp-tuning.conf
# 允许TIME_WAIT socket重用
net.ipv4.tcp_tw_reuse = 1
# 缩短TIME_WAIT时间(默认60秒,设为30秒)
net.ipv4.tcp_fin_timeout = 30
# 调整完生效
sysctl -p
注意:tcp_tw_recycle 在Linux 4.12内核之后已经移除了,不用再配了。tcp_tw_reuse 配合NAT使用时要注意,可能会引起连接异常。
坑4:ss -p需要root权限
# 不加sudo的话,进程名那一列显示为空
ss -tlnp
# 正确做法:加sudo
sudo ss -tlnp
普通用户看不了其他进程的socket信息。
实战场景(重点!结合真实运维场景)
场景1:排查端口冲突
有次部署新服务,启动时报"Address already in use"。排查过程:
# 第一步:看端口谁占了
sudo ss -tlnp | grep 8080
# 输出:LISTEN 0 128 0.0.0.0:8080 0.0.0.0:* users:(("java",pid=23456,fd=13))
# 原来是一个Java进程占着8080端口
如果确认这个进程不需要了,就kill掉再起:
# 杀死占用端口的进程
kill 23456
# 或者用fuser一句话搞定(前提是fuser已安装)
fuser -k 8080/tcp
场景2:连接数异常排查(真实案例)
有次线上服务响应变慢,我猜测是连接数爆了。用ss看:
# 先看整体情况
ss -s
发现ESTABLISHED有8000多个,但服务配置的连接池只有1000。再看:
# 看每个远程IP的连接分布
ss -tan | grep ESTAB | awk '{print $5}' | awk -F: '{print $1}' | sort | uniq -c | sort -rn | head -5
发现某个IP有5000+连接,明显是异常流量。查了业务日志,确认是某个客户端没做连接池复用,每次请求都建新连接。找对应开发改完后,连接数从8000降到了500。
场景3:TIME_WAIT过多导致端口耗尽
高并发短连接场景下,TIME_WAIT会堆积。有次遇到客户端报 "Cannot assign requested address",就是因为本地端口用完了。
# 看TIME_WAIT数量
ss -tan state time-wait | wc -l
# 输出:35000
# 看临时端口范围
cat /proc/sys/net/ipv4/ip_local_port_range
# 输出:32768 60999
# 可用的临时端口:60999-32768=28231个,不够用
解决方案:
# 1. 扩大临时端口范围
echo "10240 65535" > /proc/sys/net/ipv4/ip_local_port_range
# 2. 开启TIME_WAIT重用
echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
# 3. 缩短TIME_WAIT超时
echo 15 > /proc/sys/net/ipv4/tcp_fin_timeout
场景4:配合watch做实时监控
# 每2秒刷新一次连接统计
watch -n 2 "ss -s"
# 每2秒看TIME_WAIT数量
watch -n 2 "ss -tan state time-wait | wc -l"
# 每2秒看特定端口的状态分布
watch -n 2 "ss -tan sport = :80 | awk '{print \$1}' | sort | uniq -c | sort -rn"
部署新版本上线时,我会开着watch盯着连接数变化,确认新版本流量正常接入。
场景5:ss和awk组合做精细化分析
# 统计80端口上不同客户端IP的连接数
ss -tan sport = :80 | awk '$1 ~ /ESTAB/ {split($5, a, ":"); ip[a[1]]++} END {for (i in ip) print ip[i], i}' | sort -rn | head -10
# 查看连接建立时间(需要procfs支持)
ss -tan -o | grep :80
今日作业
一台服务器上部署了web服务(端口80),最近发现响应变慢,怀疑是连接数异常。请用ss完成以下任务:
1. 查看80端口上处于ESTABLISHED状态的连接数
2. 找出连接80端口最多的前5个客户端IP
3. 统计系统当前TIME_WAIT、ESTABLISHED、LISTEN三个状态的连接数各有多少
4. 写一条命令监控80端口的连接数变化(每2秒刷新一次)
请写出每条命令的完整内容。