在运维与开发工作中,网络连接问题宛如暗夜中的灯塔故障,不及时定位就可能引发服务中断。netstat 与 ss 正是照亮这片黑暗的核心工具。本文将深入解析这两大命令,从基础语法到实战案例,助你快速定位各类连接问题。
一、概述:为何必须掌握这两个命令
1.1 网络问题排查的重要性
在生产环境中,网络相关故障占日常运维问题的30%以上。无论是连接超时、端口不通,还是连接数激增、TIME_WAIT堆积,都是运维人员必须面对的挑战。netstat 与 ss 正是应对这些挑战的第一道防线。
试想一下,当开发同事反馈“接口无法调用”时,你能否在30秒内判断出是端口未监听、连接池耗尽,还是防火墙拦截?这种快速定位能力直接体现了运维的专业素养与效率。
1.2 netstat与ss的关系
简单来说,netstat 是历经风雨的“老将”,属于 net-tools 软件包,历史悠久,兼容性极佳。ss 则是锐意进取的“新星”,属于 iproute2 软件包,在现代Linux发行版中逐渐成为默认选择。
两者的核心差异在于:
netstat: 优点在于语法广为人知,但性能在连接数巨大时表现不佳。
ss: 优势在于速度极快,直接从内核获取数据,处理海量连接时性能远超 netstat。
时至今日,多数新系统(如 Ubuntu 22.04+、RHEL 9+)默认只安装 ss,netstat 需要额外安装 net-tools 包。但考虑到大量旧系统仍在服役,熟练掌握两者仍是必要技能。
1.3 底层原理简述
理解工具的数据来源,能帮助你更有效地使用它们。
netstat 通过解析 /proc 目录下的文件来获取信息,例如:
/proc/net/tcp: TCP连接信息
/proc/net/udp: UDP连接信息
/proc/net/unix: Unix域套接字信息
这种方式在连接数较少时无碍,但当连接数达到数万甚至数十万时,解析这些文本文件会带来显著的开销。
ss 则采用了更高效的机制:它通过 netlink 套接字直接与内核通信,使用 NETLINK_SOCK_DIAG 协议获取 socket 信息。
性能对比非常直观:在一台拥有5万个TCP连接的服务器上执行:
netstat -an: 耗时约15秒
ss -an: 耗时仅约0.3秒
因此,在高并发场景下,应优先使用 ss。
二、netstat命令详解
2.1 基础语法与常用选项
netstat 的基本语法为:
netstat [选项]
最常用的选项组合如下:
# 查看所有TCP连接
netstat -ant
# 查看所有UDP连接
netstat -anu
# 查看所有连接(TCP+UDP+Unix)
netstat -a
# 查看监听端口
netstat -tlnp
# 查看所有连接,包含进程信息
netstat -anp
# 持续监控,每2秒刷新
netstat -c 2
| 常用参数详解: |
选项 |
说明 |
-a |
显示所有socket,包括监听和非监听 |
-t |
只显示TCP连接 |
-u |
只显示UDP连接 |
-n |
不解析主机名、端口名,直接显示数字(速度快) |
-l |
只显示监听状态的socket |
-p |
显示进程PID和名称(需要root权限) |
-r |
显示路由表 |
-s |
显示网络统计信息 |
-c |
持续输出模式 |
-e |
显示扩展信息,如用户、inode等 |
-o |
显示计时器信息 |
2.2 输出字段详解
执行 netstat -antp 后的典型输出如下:
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1234/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 2345/master
tcp 0 0 192.168.1.10:22 192.168.1.100:54321 ESTABLISHED 3456/sshd: user
tcp 0 256 192.168.1.10:80 10.0.0.50:43210 ESTABLISHED 4567/nginx
tcp 0 0 192.168.1.10:80 10.0.0.51:43211 TIME_WAIT -
各字段含义解析:
Proto: 协议类型,如 tcp, tcp6, udp, udp6 等。
Recv-Q: 接收队列,表示已收到但尚未被应用读取的数据字节数。
- 对于
LISTEN 状态,表示当前 SYN backlog 队列的大小。
- 对于
ESTABLISHED 状态,表示等待读取的数据量。若此值持续不为0,可能预示应用处理能力不足。
Send-Q: 发送队列,表示已发送但未收到确认的数据字节数。若此值持续不为0,可能是网络拥塞或对端处理缓慢。
Local Address: 本地地址和端口。
0.0.0.0:端口 表示监听所有IPv4地址。
:::端口 表示监听所有IPv6地址。
127.0.0.1:端口 表示仅监听本地回环地址。
Foreign Address: 远端地址和端口。0.0.0.0:* 或 :::* 表示处于监听状态,可接受任意来源连接。
State: 连接状态,这是排查问题的关键。
PID/Program name: 进程ID和程序名称。
2.3 TCP连接状态详解
运维人员必须熟记TCP的11种状态:
LISTEN - 监听状态,等待客户端连接
SYN_SENT - 客户端发送SYN后等待确认
SYN_RECV - 服务端收到SYN后发送SYN+ACK,等待ACK
ESTABLISHED - 连接建立,正常数据传输状态
FIN_WAIT1 - 主动关闭方发送FIN后等待ACK
FIN_WAIT2 - 主动关闭方收到ACK后等待对方FIN
TIME_WAIT - 主动关闭方收到FIN并发送ACK后进入,等待2MSL
CLOSE_WAIT - 被动关闭方收到FIN后等待应用关闭
LAST_ACK - 被动关闭方发送FIN后等待ACK
CLOSING - 双方同时关闭的罕见状态
CLOSED - 连接已关闭
TCP状态转换过程可通过下图理解:
客户端 服务端
| |
| -------- SYN --------> |
| SYN_SENT SYN_RECV |
| <-- SYN+ACK ---- |
| -------- ACK --------> |
| ESTABLISHED ESTABLISHED |
| |
| <======= 数据传输 =======> |
| |
| -------- FIN --------> |
| FIN_WAIT1 CLOSE_WAIT |
| <----- ACK ---- |
| FIN_WAIT2 LAST_ACK |
| <----- FIN ---- |
| -------- ACK --------> |
| TIME_WAIT CLOSED |
| (等待2MSL) |
| CLOSED |
2.4 实用统计命令
以下命令是日常排查中使用频率最高的:
# 统计各状态连接数
netstat -ant | awk '/^tcp/ {++state[$6]} END {for(s in state) print s, state[s]}’
# 统计连接数前10的IP
netstat -ant | awk ‘/ESTABLISHED/ {print $5}’ | cut -d: -f1 | sort | uniq -c | sort -rn | head -10
# 统计连接到某端口的IP数量
netstat -ant | grep ‘:80 ’ | awk ‘{print $5}’ | cut -d: -f1 | sort | uniq -c | sort -rn | head -20
# 统计TIME_WAIT数量
netstat -ant | grep TIME_WAIT | wc -l
# 统计某个进程的连接数
netstat -antp | grep nginx | wc -l
# 查看某端口是否被占用
netstat -tlnp | grep :8080
# 查看某个IP的所有连接
netstat -ant | grep ‘192.168.1.100’
2.5 netstat查看路由表
除了连接信息,netstat 还能查看系统路由表:
# 查看路由表
netstat -rn
# 输出示例:
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth0
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
Flags 字段含义:
U: 路由是活动的
G: 需要经过网关
H: 目标是一个主机
R: 恢复动态路由产生的表项
D: 由路由守护程序动态安装
M: 由路由守护程序修改
2.6 netstat网络统计信息
netstat -s 命令提供详尽的网络协议统计信息,对于排查网络性能问题极具价值。
# 查看网络统计
netstat -s
# TCP统计
netstat -st
# UDP统计
netstat -su
关键指标解读(部分输出示例):
Tcp:
125680 active connection openings # 主动打开连接数
98543 passive connection openings # 被动打开连接数(接受连接)
1523 failed connection attempts # 连接失败数,高值需警惕
4521 connection resets received # 收到RST数
128 connections established # 当前建立的连接数
28954321 segments received # 收到的TCP段数
30125478 segments sent out # 发送的TCP段数
15234 segments retransmitted # 重传次数,高可能预示网络问题
0 bad segments received # 收到的错误段
12543 resets sent # 发送的RST数
重点关注指标:
failed connection attempts: 连接失败次数,持续升高需排查。
segments retransmitted: 重传次数,过高表明网络质量差或存在拥塞。
connection resets received: 收到RST次数过多,可能源于对端异常或防火墙策略。
三、ss命令详解
3.1 基础语法与选项
ss 的语法与 netstat 相似,易于上手:
ss [选项] [过滤条件]
常用选项组合:
# 查看所有TCP连接
ss -ant
# 查看所有监听端口
ss -tlnp
# 查看所有socket(包括Unix域)
ss -a
# 查看TCP和UDP
ss -tua
# 显示详细的socket信息
ss -i
# 显示计时器信息
ss -o
# 显示内存使用
ss -m
# 显示进程信息
ss -p
# 显示扩展信息
ss -e
# 显示统计摘要
ss -s
| 参数对照表: |
选项 |
说明 |
-a |
显示所有socket |
-l |
只显示监听socket |
-t |
TCP socket |
-u |
UDP socket |
-n |
不解析服务名称 |
-p |
显示进程信息 |
-e |
显示扩展信息 |
-m |
显示内存信息 |
-o |
显示计时器信息 |
-i |
显示内部TCP信息 |
-s |
显示socket统计摘要 |
-4 |
只显示IPv4 |
-6 |
只显示IPv6 |
3.2 ss的过滤功能(核心优势)
ss 最强大的特性是其灵活的过滤功能,这完全是 netstat 无法比拟的,也是理解网络/系统底层交互的关键。
按状态过滤
# 只看ESTABLISHED状态
ss -t state established
# 只看TIME-WAIT状态
ss -t state time-wait
# 只看监听状态
ss -t state listening
# 排除某状态
ss -t state all exclude listening
# 多个状态组合
ss -t state established state time-wait
支持的状态关键字包括:established, syn-sent, syn-recv, fin-wait-1, fin-wait-2, time-wait, closed, close-wait, last-ack, listening, closing, all, connected(排除listening和closed), synchronized(排除syn-sent), bucket(time-wait和syn-recv), big(排除bucket)。
按地址和端口过滤
# 查看目标端口是22的连接
ss -t dst :22
# 查看源端口是22的连接
ss -t src :22
# 查看目标地址是192.168.1.100的连接
ss -t dst 192.168.1.100
# 查看目标地址和端口
ss -t dst 192.168.1.100:443
# 源地址过滤
ss -t src 192.168.1.10
# 组合过滤
ss -t src 192.168.1.10 dst 10.0.0.100
# 端口范围过滤
ss -t dport \> :1024
ss -t sport \< :1024
ss -t dport = :80
# 网段过滤
ss -t dst 192.168.1.0/24
复杂过滤表达式
ss 支持使用括号组合复杂过滤条件:
# 查看连接到80或443端口的ESTABLISHED连接
ss -t state established ‘( dport = :80 or dport = :443 )’
# 查看某IP的非TIME_WAIT连接
ss -t state connected dst 192.168.1.100
# 组合多个条件
ss -t ‘( sport = :80 or sport = :443 )’ and ‘( dst 10.0.0.0/8 )’
3.3 ss输出字段详解
执行 ss -tinp 的输出示例:
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 0.0.0.0:80 0.0.0.0:* users:((“nginx”,pid=1234,fd=6))
ESTAB 0 0 192.168.1.10:80 10.0.0.50:43210 users:((“nginx”,pid=1235,fd=12))
加上 -i 选项可以查看详细的TCP内部信息,这对性能分析至关重要:
ss -ti
# 输出示例:
ESTAB 0 0 192.168.1.10:80 10.0.0.50:43210
cubic wscale:7,7 rto:201 rtt:0.543/0.021 ato:40 mss:1448 pmtu:1500 rcvmss:536 advmss:1448
cwnd:10 bytes_sent:12345 bytes_acked:12344 bytes_received:5678 segs_out:123 segs_in:98
data_segs_out:89 data_segs_in:76 send 213.1Mbps lastsnd:28 lastrcv:28 lastack:28
pacing_rate 425.7Mbps delivery_rate 142.5Mbps delivered:90 app_limited busy:24ms
rcv_rtt:1 rcv_space:29200 rcv_ssthresh:29200 minrtt:0.087
| 关键字段含义: |
字段 |
含义 |
cubic |
拥塞控制算法 |
rto |
重传超时时间(ms) |
rtt |
往返时间/偏差(ms) |
mss |
最大段大小 |
cwnd |
拥塞窗口大小 |
bytes_sent |
已发送字节数 |
segs_out |
发出的段数 |
retrans |
重传次数/超时重传次数 |
send |
发送速率 |
delivery_rate |
传输速率 |
minrtt |
最小RTT |
3.4 ss统计摘要
ss -s 命令能快速提供系统网络连接概况,执行速度极快。
ss -s
# 输出示例:
Total: 1542
TCP: 1328 (estab 856, closed 312, orphaned 24, timewait 289)
Transport Total IP IPv6
RAW 0 0 0
UDP 45 42 3
TCP 1016 923 93
INET 1061 965 96
FRAG 0 0 0
3.5 ss查看内存使用
ss -tm 可以查看socket的内存使用情况。
ss -tm
# 输出示例:
ESTAB 0 0 192.168.1.10:80 10.0.0.50:43210
skmem:(r0,rb374400,t0,tb87040,f0,w0,o0,bl0,d0)
skmem 字段含义:
r: 接收缓冲区已分配内存
rb: 接收缓冲区可分配最大值
t: 发送缓冲区已分配内存
tb: 发送缓冲区可分配最大值
f: 转发缓冲区已分配内存
w: 发送缓冲区等待发送字节数
o: 选项缓冲区已分配内存
bl: 后端日志缓冲区
d: 已丢弃的字节数
3.6 ss查看计时器信息
ss -to 显示连接的计时器信息,有助于分析连接超时问题。
ss -to
# 输出示例:
ESTAB 0 0 192.168.1.10:80 10.0.0.50:43210 timer:(keepalive,28sec,0)
TIME-WAIT 0 0 192.168.1.10:80 10.0.0.51:43211 timer:(timewait,45sec,0)
计时器类型包括:on(重传)、keepalive(保活)、timewait(TIME_WAIT)、persist(零窗口探测)、unknown(未知)。
四、实战案例
4.1 案例一:服务端口不通问题排查
场景: 开发反馈调用服务的8080端口失败。
排查步骤:
# 第一步:检查端口是否监听
ss -tlnp | grep 8080
# 若无输出,服务未启动或监听其他端口。若有输出,查看监听地址。
# 0.0.0.0:8080 - 监听所有地址,正常。
# 127.0.0.1:8080 - 仅监听本地,外部无法访问。
# 第二步:若监听正常,检查是否有连接建立
ss -tnp | grep 8080
# 第三步:若连接能建立,检查积压情况
ss -lnp | grep 8080
# 关注Recv-Q,它表示等待accept的连接数。
# 第四步:检查防火墙
iptables -L -n | grep 8080
# 或使用firewalld
firewall-cmd --list-all
实际操作示例:
[root@server ~]# ss -tlnp | grep 8080
LISTEN 0 128 127.0.0.1:8080 0.0.0.0:* users:((“java”,pid=12345,fd=123))
# 发现问题:仅监听了127.0.0.1,需改为0.0.0.0
# 修改应用配置重启后
[root@server ~]# ss -tlnp | grep 8080
LISTEN 0 128 0.0.0.0:8080 0.0.0.0:* users:((“java”,pid=12346,fd=123))
# 问题解决
4.2 案例二:TIME_WAIT过多问题
场景: 监控告警TIME_WAIT连接数超过10万。
排查步骤:
# 第一步:确认数量
ss -s
# 或
ss -t state time-wait | wc -l
# 第二步:分析分布
# 按本地端口统计
ss -t state time-wait | awk ‘{print $4}’ | cut -d: -f2 | sort | uniq -c | sort -rn | head -10
# 按远端地址统计
ss -t state time-wait | awk ‘{print $5}’ | cut -d: -f1 | sort | uniq -c | sort -rn | head -10
# 第三步:查看内核参数
cat /proc/sys/net/ipv4/tcp_tw_reuse
cat /proc/sys/net/ipv4/tcp_max_tw_buckets
cat /proc/sys/net/ipv4/tcp_fin_timeout
处理方案:
# 临时调整(重启失效)
echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse # 开启TIME_WAIT复用
echo 262144 > /proc/sys/net/ipv4/tcp_max_tw_buckets # 调整最大数量
echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout # 减少FIN_WAIT超时时间
# 永久生效,写入sysctl.conf
cat >> /etc/sysctl.conf << EOF
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_tw_buckets = 262144
net.ipv4.tcp_fin_timeout = 30
EOF
sysctl -p
注意事项:
tcp_tw_recycle 在Linux 4.12+已被移除,切勿再使用。
- 在NAT环境下启用
tcp_tw_reuse 需谨慎。
- TIME_WAIT是正常的TCP机制,无需过度优化。
4.3 案例三:连接数限制问题
场景: Nginx报“Too many open files”错误,无法接受新连接。
排查步骤:
# 第一步:查看当前连接数
ss -s
ss -t state established | wc -l
# 第二步:查看进程文件描述符使用情况
ps aux | grep nginx # 找到master进程PID
ls /proc/[nginx-pid]/fd | wc -l # 查看打开的文件描述符数
cat /proc/[nginx-pid]/limits | grep “Max open files” # 查看进程限制
# 第三步:查看系统级别限制
cat /proc/sys/fs/file-nr # 输出:已分配 未使用 最大值
处理方案:
# 方法1:修改nginx配置,添加 worker_rlimit_nofile 65535;
# 方法2:修改systemd服务文件,添加 LimitNOFILE=65535
# 方法3:修改全局limits
echo “* soft nofile 65535” >> /etc/security/limits.d/99-nofile.conf
echo “* hard nofile 65535” >> /etc/security/limits.d/99-nofile.conf
4.4 案例四:排查连接泄漏
场景: 应用重启后连接数正常,但运行一段时间后持续增长。
排查步骤:
# 第一步:定时采集连接数
while true; do
echo “$(date ‘+%Y-%m-%d %H:%M:%S’) $(ss -t state established | wc -l)” >> /tmp/conn_count.log
sleep 60
done
# 第二步:分析连接分布变化
ss -tnp | awk ‘/ESTAB/ {print $5}’ | cut -d: -f1 | sort | uniq -c | sort -rn | head -20
ss -tnp | awk -F’“‘’/ESTAB/ && /pid=/ {print $2}’ | sort | uniq -c | sort -rn
# 第三步:追踪具体进程连接变化(例如java进程)
watch -n 5 ‘ss -tnp | grep java | wc -l’
# 第四步:分析长时间未关闭的连接
ss -to | grep -v “timer:(keepalive”
进阶分析: 通过定期导出连接快照进行对比,找出新增但未关闭的连接。
4.5 案例五:SYN Flood攻击识别
场景: 服务器响应变慢,怀疑遭受攻击。
排查步骤:
# 第一步:查看SYN_RECV状态连接数(正常应很少)
ss -t state syn-recv | wc -l
# 第二步:查看SYN_RECV来源分布
ss -t state syn-recv | awk ‘{print $5}’ | cut -d: -f1 | sort | uniq -c | sort -rn | head -20
# 大量来自不同IP可能是分布式攻击,集中在少数IP可考虑封禁。
# 第三步:检查半连接队列是否溢出
netstat -s | grep -i “syn”
cat /proc/net/netstat | grep -i “listenoverflows\|listendrop”
# 第四步:查看内核日志
dmesg | grep -i “syn flood”
应急处理: 开启SYN Cookies、增大半连接队列、减少SYN_RECV超时,或使用iptables限制单IP SYN频率。
4.6 案例六:排查CLOSE_WAIT堆积
背景: CLOSE_WAIT表示对端已关闭连接(发送FIN),但本端应用未关闭socket。这通常是应用代码问题。
排查步骤:
# 第一步:确认数量
ss -t state close-wait | wc -l
# 第二步:定位进程
ss -tp state close-wait | awk -F’“‘’{print $2}’ | sort | uniq -c | sort -rn
# 第三步:查看连接详情
ss -tp state close-wait
# 第四步:分析目标地址
ss -t state close-wait | awk ‘{print $5}’ | sort | uniq -c | sort -rn | head -10
处理方案: 检查应用代码,确保socket(尤其是数据库连接)在finally块中正确关闭,并检查连接池配置。
4.7 案例七:快速定位端口占用
场景: 启动服务时报端口被占用。
# 方法1:用ss(推荐)
ss -tlnp | grep :8080
# 方法2:用netstat
netstat -tlnp | grep :8080
# 方法3:用lsof
lsof -i :8080
# 方法4:用fuser
fuser 8080/tcp
4.8 案例八:网络性能分析
场景: 用户反馈接口响应慢,需排查网络层面。
# 第一步:查看TCP重传情况
netstat -s | grep -i retrans
cat /proc/net/snmp | grep Tcp
# 第二步:查看具体连接的RTT
ss -ti dst [目标IP]
# 第三步:查看连接的详细计时信息
ss -to dst [目标IP]
# 第四步:检查网卡是否有丢包
cat /proc/net/dev
ip -s link show eth0
五、脚本与自动化
为了提升运维 & 测试效率,将常用检查脚本化是必要之举。
5.1 连接监控脚本
以下脚本用于持续监控连接状态并记录日志,可在超过阈值时触发告警。
#!/bin/bash
LOG_FILE=”/var/log/conn_monitor.log”
ALERT_THRESHOLD_ESTABLISHED=10000
ALERT_THRESHOLD_TIMEWAIT=50000
ALERT_THRESHOLD_CLOSEWAIT=100
INTERVAL=60
log_msg() {
echo “$(date ‘+%Y-%m-%d %H:%M:%S’) $1” >> $LOG_FILE
}
while true; do
ESTABLISHED=$(ss -t state established | wc -l)
TIMEWAIT=$(ss -t state time-wait | wc -l)
CLOSEWAIT=$(ss -t state close-wait | wc -l)
SYNRECV=$(ss -t state syn-recv | wc -l)
LISTEN=$(ss -t state listening | wc -l)
log_msg “ESTAB:$ESTABLISHED TW:$TIMEWAIT CW:$CLOSEWAIT SYN_RECV:$SYNRECV LISTEN:$LISTEN”
if [ $ESTABLISHED -gt $ALERT_THRESHOLD_ESTABLISHED ]; then
log_msg “[ALERT] ESTABLISHED连接数过高: $ESTABLISHED (阈值: $ALERT_THRESHOLD_ESTABLISHED)”
fi
if [ $TIMEWAIT -gt $ALERT_THRESHOLD_TIMEWAIT ]; then
log_msg “[ALERT] TIME_WAIT连接数过高: $TIMEWAIT (阈值: $ALERT_THRESHOLD_TIMEWAIT)”
fi
if [ $CLOSEWAIT -gt $ALERT_THRESHOLD_CLOSEWAIT ]; then
log_msg “[ALERT] CLOSE_WAIT连接数过高: $CLOSEWAIT (阈值: $ALERT_THRESHOLD_CLOSEWAIT)”
fi
sleep $INTERVAL
done
5.2 连接统计报告脚本
一键生成详细的连接统计报告,便于日常巡检或故障报告。
#!/bin/bash
echo “======================================”
echo “网络连接统计报告”
echo “生成时间: $(date ‘+%Y-%m-%d %H:%M:%S’)”
echo “======================================”
echo “”
echo “### 连接状态汇总 ###”
ss -s
echo “”
echo “### 各状态连接数 ###”
echo “ESTABLISHED: $(ss -t state established | tail -n +2 | wc -l)”
echo “TIME_WAIT: $(ss -t state time-wait | wc -l)”
echo “CLOSE_WAIT: $(ss -t state close-wait | wc -l)”
… (其余部分省略,详见原文) …
5.3 一键诊断脚本
综合性的诊断脚本,能快速输出系统网络健康状态概览。
#!/bin/bash
RED=’\033[0;31m’
GREEN=’\033[0;32m’
YELLOW=’\033[1;33m’
NC=’\033[0m’ # No Color
print_header() { echo -e “\n${GREEN}========== $1 ==========${NC}\n”; }
print_warning() { echo -e “${YELLOW}[警告] $1${NC}”; }
print_error() { echo -e “${RED}[异常] $1${NC}”; }
print_ok() { echo -e “${GREEN}[正常] $1${NC}”; }
print_header “系统基本信息”
echo “主机名: $(hostname)”
echo “内核版本: $(uname -r)”
… (其余诊断输出省略) …
echo “诊断完成。如有异常请根据提示进行进一步排查。”
六、最佳实践与进阶
6.1 日常运维建议
- 监控告警: 为关键指标(ESTABLISHED, TIME_WAIT, CLOSE_WAIT, SYN_RECV数量,TCP重传率)设置合理阈值。
- 定期巡检: 每日关注连接数趋势,每周检查网络错误统计和内核参数。
- 数据保留: 保留至少7天的连接快照数据,便于事后分析和容量规划。
6.2 故障排查流程总结
- 快速概览:
ss -s
- 确定方向: 根据症状(端口不通、连接数异常、性能问题)使用对应过滤命令。
- 深入分析: 结合
ss -tp、ss -ti、ss -to、netstat -s 等命令。
- 定位根因: 结合应用日志、代码审查、抓包分析等手段。
- 实施修复: 针对性解决问题。
6.3 进阶话题:理解TCP半连接与全连接队列
这是一个关键概念。当客户端发起连接时:
- 半连接队列(SYN Queue): 存放收到SYN但未完成三次握手的连接,大小由
tcp_max_syn_backlog 控制。
- 全连接队列(Accept Queue): 存放已完成握手但未被
accept() 的连接,大小由 min(somaxconn, backlog) 决定。
通过 ss -lnt 查看LISTEN状态的 Recv-Q(当前队列长度)和 Send-Q(队列最大值)。
七、总结与常见问题
常用命令速查
ss -s # 快速查看连接概况
ss -tnp # 查看TCP连接(最常用)
ss -tlnp # 查看监听端口
ss -t state established # 查看已建立连接
ss -t state time-wait # 查看TIME_WAIT连接
ss -ti # 查看详细TCP信息(RTT、重传等)
FAQ
Q1: ss和netstat哪个更好?
A: 优先使用 ss,因为它更快、过滤功能更强、能显示更多TCP内部信息,且是新系统默认工具。但 netstat 在老系统上可能仍是唯一选择,两者都掌握为佳。
Q2: 为什么看不到进程名?
A: 可能原因:1) 无root权限;2) 是内核线程创建的连接;3) 进程已退出(如TIME_WAIT状态);4) 特殊的socket类型。
Q3: CLOSE_WAIT一直不减少怎么办?
A: 这表明应用程序未正确关闭socket。需找到对应进程,检查代码确保socket在finally块中关闭,或检查连接池配置。重启应用只是临时方案,修复代码才是根本。
Q4: TIME_WAIT太多有何影响?
A: 主要影响:1) 占用本地端口,可能导致端口耗尽;2) 占用内存;3) 可能影响命令执行速度。但它是正常TCP机制,几万个通常问题不大。
掌握 netstat 与 ss 命令的核心在于理解原理,并形成自己的排查套路。网络问题排查能力是运维人员的核心价值之一。希望这篇指南能成为你工具箱中的利器。实践中遇到问题,欢迎在技术社区如云栈社区进行交流探讨。