每个后端工程师都用过
netstat -an,但很少有人真正掌握了 Linux
网络诊断工具链的全部能力。ss 比
netstat
快两个数量级,但它的过滤语法鲜为人知。ip
命令族替代了
ifconfig、route、arp、netstat -r
四个传统工具,功能更强大也更统一。conntrack 是
NAT
和防火墙的连接追踪表,高并发服务的隐形瓶颈常常藏在这里。
本文系统讲解这些工具的工程用法——不是命令手册式的罗列,而是聚焦”在什么场景下用什么命令解决什么问题”。
一、ss:现代 Socket 统计工具
1.1 ss vs netstat:为什么要切换
netstat 通过读取
/proc/net/tcp、/proc/net/udp
等文件获取信息,在连接数多时非常慢:
| 连接数 | netstat 耗时 | ss 耗时 | 倍数 |
|---|---|---|---|
| 1,000 | 0.3 s | 0.01 s | 30x |
| 10,000 | 3.2 s | 0.02 s | 160x |
| 100,000 | 35 s | 0.08 s | 437x |
| 1,000,000 | > 5 min | 0.5 s | > 600x |
ss 使用
netlink(SOCK_DIAG)接口直接从内核获取 socket
信息,跳过了 /proc
文件系统的文本解析开销。在百万连接的服务器上,netstat
可能跑不出结果,ss 依然秒级返回。
1.2 ss 基础用法
# 列出所有 TCP 连接
ss -tan
# 列出所有监听端口
ss -tlnp
# 列出所有 UDP socket
ss -uan
# 显示详细信息(包含计时器、内存使用)
ss -tanmi
# 常用选项
# -t TCP
# -u UDP
# -a 所有状态(包括 LISTEN)
# -n 不解析域名(速度快)
# -l 只显示 LISTEN
# -p 显示进程信息
# -m 显示内存使用
# -i 显示 TCP 内部信息(cwnd、rtt 等)
# -e 显示扩展信息(UID、cookie 等)
# -o 显示计时器信息1.3 ss 过滤语法
ss 的过滤语法是它最强大也最被低估的功能。语法分为状态过滤和地址/端口过滤两类。
状态过滤:
# 只显示 ESTABLISHED 连接
ss -tan state established
# 只显示 TIME-WAIT
ss -tan state time-wait
# 只显示 CLOSE-WAIT(常用于检测连接泄漏)
ss -tan state close-wait
# 多状态组合
ss -tan state established state close-wait
# 预定义状态组
ss -tan state connected # 所有已连接状态
ss -tan state synchronized # 已同步状态(不含 SYN-SENT/SYN-RECV)
ss -tan state bucket # TIME-WAIT 和 SYN-RECV(内核用 mini socket)
ss -tan state big # 所有非 bucket 状态TCP 状态过滤支持的值:
established syn-sent syn-recv fin-wait-1 fin-wait-2
time-wait close close-wait last-ack listening
closing all connected synchronized bucket big
地址/端口过滤:
# 过滤目标端口
ss -tan 'dport = :443'
# 过滤源端口
ss -tan 'sport = :8080'
# 过滤目标 IP
ss -tan 'dst 10.0.1.100'
# 过滤源 IP
ss -tan 'src 10.0.1.50'
# 组合过滤
ss -tan 'dport = :443 and dst 10.0.1.100'
ss -tan 'sport = :8080 or sport = :8081'
# 端口范围
ss -tan 'dport >= :1024 and dport <= :65535'
# 排除某些端口
ss -tan 'dport != :22'
# 过滤特定子网
ss -tan 'dst 10.0.1.0/24'1.4 ss 的 TCP 内部信息
ss -ti 显示 TCP
连接的内核参数,这些信息对诊断性能问题至关重要:
ss -ti 'dport = :443' | head -20输出示例:
ESTAB 0 0 10.0.1.50:54321 10.0.2.100:443
cubic wscale:7,7 rto:204 rtt:15.2/0.5 ato:40 mss:1448 pmtu:1500
rcvmss:1448 advmss:1448 cwnd:10 bytes_sent:1234 bytes_acked:1234
bytes_received:5678 segs_out:15 segs_in:12 data_segs_out:8 data_segs_in:10
send 7.6Mbps lastsnd:120 lastrcv:80 lastack:80
pacing_rate 15.2Mbps delivery_rate 6.8Mbps delivered:9
busy:200ms rcv_rtt:16 rcv_space:29200 rcv_ssthresh:29200
minrtt:14.8
各字段含义:
| 字段 | 含义 | 工程关注点 |
|---|---|---|
cubic |
拥塞控制算法 | 是否使用了预期的算法(BBR?) |
rto:204 |
重传超时,单位 ms | 过大说明 RTT 高或有重传历史 |
rtt:15.2/0.5 |
平滑 RTT / RTT 方差 | 方差大说明延迟抖动严重 |
cwnd:10 |
拥塞窗口,单位 MSS | 过小说明拥塞或刚从丢包中恢复 |
mss:1448 |
最大段大小 | 1448 = 1500 MTU - 40 (IP+TCP) - 12 (TCP options) |
pmtu:1500 |
路径 MTU | 小于 1500 说明路径上有 MTU 限制 |
send 7.6Mbps |
当前发送速率 | 与预期带宽对比 |
rcv_space:29200 |
接收窗口通告值 | 过小可能限制吞吐量 |
minrtt:14.8 |
观测到的最小 RTT | 最接近物理链路延迟的值 |
1.5 实战:用 ss 做连接审计
场景 1:检测 CLOSE_WAIT 泄漏
CLOSE_WAIT 表示对端已经关闭连接(发了
FIN),但本端还没调用
close()。如果持续增长,说明应用有连接泄漏:
# 统计 CLOSE_WAIT 按进程分组
ss -tanp state close-wait | \
awk '{print $NF}' | \
grep -oP 'users:\(\("\K[^"]+' | \
sort | uniq -c | sort -rn
# 持续监控 CLOSE_WAIT 趋势
watch -n 5 'ss -tan state close-wait | wc -l'
# 查看具体哪些连接处于 CLOSE_WAIT
ss -tanp state close-wait | column -t场景 2:查找端口占用
# 谁在用 8080 端口
ss -tlnp 'sport = :8080'
# LISTEN 0 4096 *:8080 *:* users:(("java",pid=12345,fd=88))
# 如果端口被占用但找不到进程
# 可能是 TIME_WAIT 状态的连接占着
ss -tan 'sport = :8080' state time-wait | wc -l场景 3:统计连接状态分布
# TCP 状态分布
ss -tan | awk 'NR>1 {print $1}' | sort | uniq -c | sort -rn
# 15234 ESTAB
# 3421 TIME-WAIT
# 234 CLOSE-WAIT
# 56 FIN-WAIT-2
# 12 SYN-SENT
# 8 LAST-ACK
# 3 SYN-RECV
# 按目标 IP 统计连接数(找连接最多的目标)
ss -tan state established | awk 'NR>1 {print $5}' | \
awk -F: '{print $1}' | sort | uniq -c | sort -rn | head -10
# 按进程统计连接数
ss -tanp state established | \
grep -oP 'users:\(\("\K[^"]+' | \
sort | uniq -c | sort -rn二、ip 命令族:统一的网络配置工具
2.1 ip 命令替代关系
ip
命令族统一了原来分散在多个工具中的功能:
| 传统工具 | ip 等价命令 | 功能 |
|---|---|---|
ifconfig |
ip addr / ip link |
接口地址和状态 |
route |
ip route |
路由表 |
arp |
ip neigh |
ARP/NDP 邻居表 |
netstat -r |
ip route show |
路由表(同上) |
netstat -i |
ip -s link |
接口统计 |
iptunnel |
ip tunnel |
隧道管理 |
brctl |
ip link / bridge |
网桥管理 |
2.2 ip link:接口管理
# 简洁列出所有接口
ip -br link show
# lo UNKNOWN 00:00:00:00:00:00 <LOOPBACK,UP,LOWER_UP>
# eth0 UP aa:bb:cc:dd:ee:ff <BROADCAST,MULTICAST,UP,LOWER_UP>
# docker0 DOWN 02:42:xx:xx:xx:xx <NO-CARRIER,BROADCAST,MULTICAST,UP>
# 详细统计(收发字节数、错误数)
ip -s link show eth0
# 设置接口 UP/DOWN
ip link set eth0 up
ip link set eth0 down
# 修改 MTU
ip link set eth0 mtu 9000
# 查看接口详细信息(包括 driver)
ip -d link show eth02.3 ip addr:地址管理
# 简洁列出所有地址
ip -br addr show
# lo UNKNOWN 127.0.0.1/8 ::1/128
# eth0 UP 10.0.1.50/24 fe80::1/64
# 添加地址
ip addr add 10.0.1.51/24 dev eth0
# 删除地址
ip addr del 10.0.1.51/24 dev eth0
# 只看 IPv4
ip -4 addr show
# 只看 IPv6
ip -6 addr show2.4 ip route:路由管理
# 查看路由表
ip route show
# default via 10.0.1.1 dev eth0 proto dhcp metric 100
# 10.0.1.0/24 dev eth0 proto kernel scope link src 10.0.1.50
# 172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
# 查看到特定目标的路由
ip route get 8.8.8.8
# 8.8.8.8 via 10.0.1.1 dev eth0 src 10.0.1.50
# 添加静态路由
ip route add 10.0.2.0/24 via 10.0.1.1 dev eth0
# 添加策略路由(多出口场景)
ip rule add from 10.0.1.0/24 table 100
ip route add default via 10.0.1.1 dev eth0 table 100
# 查看路由缓存(已废弃,现代内核用 FIB)
ip route show cache
# 查看特定路由表
ip route show table all | head -202.5 ip neigh:邻居表(ARP/NDP)
# 查看 ARP 表
ip neigh show
# 10.0.1.1 dev eth0 lladdr aa:bb:cc:dd:ee:ff REACHABLE
# 10.0.1.2 dev eth0 lladdr 11:22:33:44:55:66 STALE
# 10.0.1.3 dev eth0 FAILED
# 各状态含义
# REACHABLE: 最近确认可达
# STALE: 上次确认已过期,下次使用时会重新验证
# DELAY: 正在等待确认
# PROBE: 正在发送 ARP 探测
# FAILED: ARP 解析失败
# INCOMPLETE: ARP 请求已发送,等待响应
# 手动添加 ARP 条目
ip neigh add 10.0.1.100 lladdr aa:bb:cc:dd:ee:ff dev eth0
# 刷新 ARP 缓存
ip neigh flush dev eth0
# 监控 ARP 变化
ip monitor neigh2.6 ip 命令的 JSON 输出
ip 命令支持 JSON 输出,方便脚本处理:
# JSON 格式输出
ip -j addr show eth0 | jq '.[0].addr_info[] | select(.family == "inet")'
# 获取 IP 地址
ip -j addr show eth0 | jq -r '.[0].addr_info[] | select(.family == "inet") | .local'
# 获取默认路由网关
ip -j route show default | jq -r '.[0].gateway'
# 批量检查接口状态
ip -j link show | jq '.[] | {name: .ifname, state: .operstate, mtu: .mtu}'三、conntrack:连接追踪
3.1 conntrack 基础
conntrack 是 Linux netfilter 框架的连接追踪模块。每个经过 netfilter 的连接都会在 conntrack 表中创建一个条目。NAT、有状态防火墙规则都依赖它。
# 查看 conntrack 表大小
cat /proc/sys/net/netfilter/nf_conntrack_count # 当前条目数
cat /proc/sys/net/netfilter/nf_conntrack_max # 最大条目数
# 列出所有连接跟踪条目
conntrack -L | head -10
# tcp 6 431999 ESTABLISHED src=10.0.1.50 dst=10.0.2.100 sport=54321 dport=443
# src=10.0.2.100 dst=10.0.1.50 sport=443 dport=54321 [ASSURED] mark=0
# 按协议统计
conntrack -L 2>/dev/null | awk '{print $1}' | sort | uniq -c | sort -rn
# 85234 tcp
# 3456 udp
# 123 icmp
# 按状态统计(TCP)
conntrack -L -p tcp 2>/dev/null | \
grep -oP '(ESTABLISHED|TIME_WAIT|CLOSE_WAIT|SYN_SENT|FIN_WAIT|CLOSE|LAST_ACK|SYN_RECV)' | \
sort | uniq -c | sort -rn3.2 conntrack 表满的诊断
conntrack 表满是高并发服务器的常见问题,表现为新连接被随机丢弃:
# 检查是否表满
dmesg | grep "nf_conntrack: table full"
# [12345.678] nf_conntrack: table full, dropping packet
# 当前使用率
CURR=$(cat /proc/sys/net/netfilter/nf_conntrack_count)
MAX=$(cat /proc/sys/net/netfilter/nf_conntrack_max)
echo "Usage: $CURR / $MAX ($(( CURR * 100 / MAX ))%)"
# 查看各超时参数
sysctl -a 2>/dev/null | grep conntrack.*timeout | head -10
# net.netfilter.nf_conntrack_tcp_timeout_established = 432000 (5 天!)
# net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
# net.netfilter.nf_conntrack_tcp_timeout_close = 10
# 优化:缩短超时
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=3600 # 1 小时
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_time_wait=30 # 30 秒
# 优化:增大表上限
sysctl -w net.netfilter.nf_conntrack_max=1048576
# 优化:增大 hash 表大小(减少冲突)
echo 262144 > /sys/module/nf_conntrack/parameters/hashsize3.3 conntrack 实战查询
# 查看到特定目标的连接
conntrack -L -d 10.0.2.100
# 查看特定端口的连接
conntrack -L -p tcp --dport 443
# 查看 NAT 映射
conntrack -L -n
# 删除特定连接(强制重建)
conntrack -D -s 10.0.1.50 -d 10.0.2.100 -p tcp --dport 443
# 实时监控连接事件
conntrack -E
# [NEW] tcp 6 120 SYN_SENT src=10.0.1.50 dst=10.0.2.100 ...
# [UPDATE] tcp 6 431999 ESTABLISHED src=10.0.1.50 dst=10.0.2.100 ...
# [DESTROY] tcp 6 src=10.0.1.50 dst=10.0.2.100 ...
# 统计每秒新建连接数
conntrack -E 2>/dev/null | pv -l -i 5 > /dev/null四、/proc/net/ 文件解读
4.1 关键文件清单
/proc/net/
下的文件是内核网络状态的直接映射:
# TCP 连接(ss/netstat 的数据来源)
cat /proc/net/tcp | head -5
# sl local_address rem_address st tx_queue rx_queue ...
# 0: 0100007F:1F90 00000000:0000 0A 00000000:00000000 ...
# 0A = 10 = LISTEN 状态
# 地址是十六进制小端序
# TCP 统计
cat /proc/net/snmp | grep Tcp
# Tcp: RtoAlgorithm RtoMin RtoMax MaxConn ActiveOpens PassiveOpens ...
# Tcp: 1 200 120000 -1 12345 67890 ...
# 网络统计(更详细)
cat /proc/net/netstat | head -4
# softnet 统计
cat /proc/net/softnet_stat
# 每行一个 CPU,列含义:
# col1: 收到的帧总数
# col2: 因 netdev_budget 用完而 drop 的帧数(> 0 需要关注)
# col3: 因 time_squeeze 而延迟处理的次数4.2 /proc/net/snmp 的工程解读
这个文件提供了全局的协议统计,是诊断网络问题的重要指标源:
# 解析 TCP 关键指标
awk '/^Tcp:/ {if(NR%2==0) {
printf "ActiveOpens: %s\n", $6;
printf "PassiveOpens: %s\n", $7;
printf "AttemptFails: %s\n", $8;
printf "EstabResets: %s\n", $9;
printf "CurrEstab: %s\n", $10;
printf "InSegs: %s\n", $11;
printf "OutSegs: %s\n", $12;
printf "RetransSegs: %s\n", $13;
printf "InErrs: %s\n", $14;
printf "OutRsts: %s\n", $15;
}}' /proc/net/snmp关键指标解读:
| 指标 | 含义 | 异常判断 |
|---|---|---|
AttemptFails |
连接尝试失败次数 | 持续增长→对端不可达或防火墙 |
EstabResets |
已建立连接被 RST 次数 | 持续增长→应用异常关闭或中间设备干扰 |
RetransSegs |
重传的段数 | RetransSegs / OutSegs > 1% →
网络质量差 |
InErrs |
接收到的错误段 | 持续增长→校验和错误或数据损坏 |
OutRsts |
发出的 RST 数 | 高→大量连接到未监听端口 |
4.3 监控脚本:TCP 指标持续采集
#!/bin/bash
# tcp-metrics.sh — TCP 指标持续采集
INTERVAL="${1:-5}"
echo "timestamp,active_opens,passive_opens,attempt_fails,estab_resets,retrans_segs,in_errs,out_rsts,curr_estab"
PREV=""
while true; do
CURR=$(awk '/^Tcp:/ && NR%2==0 {print $6,$7,$8,$9,$10,$11,$12,$13,$14,$15}' /proc/net/snmp)
TS=$(date '+%Y-%m-%d %H:%M:%S')
if [ -n "$PREV" ]; then
# 计算增量
paste <(echo "$PREV") <(echo "$CURR") | \
awk -v ts="$TS" '{
printf "%s,%d,%d,%d,%d,%d,%d,%d,%s\n",
ts, $11-$1, $12-$2, $13-$3, $14-$4, $15-$5,
$18-$8, $19-$9, $20
}'
fi
PREV="$CURR"
sleep "$INTERVAL"
done输出示例:
timestamp,active_opens,passive_opens,attempt_fails,estab_resets,retrans_segs,in_errs,out_rsts,curr_estab
2025-08-12 14:30:05,234,567,2,1,45,0,5,15234
2025-08-12 14:30:10,245,580,0,0,38,0,3,15267
2025-08-12 14:30:15,212,554,15,8,890,0,45,15190 ← 异常:attempt_fails 和 retrans 飙升
五、netstat 的遗留价值
5.1 netstat 仍然有用的场景
虽然 ss 在性能和功能上全面超越 netstat,但 netstat 在少数场景下仍有价值:
# 协议统计(这个 netstat 的输出比 ss 更直观)
netstat -s | head -40
# Tcp:
# 23456 active connection openings
# 67890 passive connection openings
# 234 failed connection attempts
# 56 connection resets received
# 15234 connections established
# 890123 segments received
# 876543 segments sent out
# 4567 segments retransmitted ← 重传数
# 12 bad segments received
# 345 resets sent
# 多播组成员
netstat -g
# Unix domain socket
netstat -x
# 或 ss -x5.2 从 netstat 到 ss 的迁移对照
| netstat 命令 | ss 等价命令 | 说明 |
|---|---|---|
netstat -an |
ss -an |
所有连接 |
netstat -tlnp |
ss -tlnp |
TCP 监听端口 |
netstat -s |
ss -s + nstat |
协议统计 |
netstat -r |
ip route show |
路由表 |
netstat -i |
ip -s link show |
接口统计 |
netstat -g |
ip maddr show |
多播组 |
六、nstat:增量网络统计
nstat
是一个被低估的工具,它显示增量网络统计,比
netstat -s 更适合实时监控:
# 显示自上次调用以来的增量统计
nstat -s
# 持续输出(每 5 秒)
nstat -n 5
# 只看 TCP 相关
nstat -s | grep -i tcp
# 重要指标
nstat -s | grep -E "TcpRetransSegs|TcpTimeouts|TcpAbortOnTimeout|TCPLostRetransmit"
# TcpRetransSegs 456 # 这个周期内的重传段数
# TcpTimeouts 12 # 超时次数
# TCPLostRetransmit 3 # 重传也丢了nstat
的工程价值:当你怀疑有网络问题但不知道具体是什么时,开一个
nstat -n 5,看哪些计数器在跳——它能快速缩小排查范围。
七、综合实战场景
7.1 场景一:排查 TIME_WAIT 堆积
# 1. 确认 TIME_WAIT 数量
ss -tan state time-wait | wc -l
# 45000 ← 大量 TIME_WAIT
# 2. 看 TIME_WAIT 连接到哪里
ss -tan state time-wait | awk '{print $5}' | awk -F: '{print $1}' | \
sort | uniq -c | sort -rn | head -5
# 35000 10.0.2.100 ← 绝大部分连到这个 IP
# 3. 这个 IP 是什么服务?
# → 数据库/Redis/下游 API 服务
# 4. 根因分析:短连接太多,每个请求都新建 TCP 连接
# TIME_WAIT 默认持续 60 秒(2 * MSL)
# 5. 解决方案
# 方案 A:启用连接池(根本解决)
# 方案 B:启用 tcp_tw_reuse(允许复用 TIME_WAIT 连接)
sysctl -w net.ipv4.tcp_tw_reuse=1
# 方案 C:减少 TIME_WAIT 持续时间(不推荐,改内核行为)7.2 场景二:排查连接泄漏
# 1. CLOSE_WAIT 持续增长
watch -n 10 'ss -tan state close-wait | wc -l'
# 从 50 → 200 → 500 → 持续增长
# 2. 找到泄漏的进程
ss -tanp state close-wait | awk '{print $NF}' | sort | uniq -c | sort -rn
# 480 users:(("myapp",pid=12345,fd=...))
# 3. 检查进程的文件描述符
ls /proc/12345/fd | wc -l # 总 FD 数
ls -la /proc/12345/fd | grep socket | wc -l # socket FD 数
# 4. 检查 FD 限制
cat /proc/12345/limits | grep "Max open files"
# Max open files 1024 1048576
# 5. 用 lsof 查看具体的 CLOSE_WAIT 连接
lsof -p 12345 -n -i | grep CLOSE_WAIT | head -10
# 6. 根因:应用未正确处理对端关闭
# → 检查 HTTP 客户端是否正确关闭 response body
# Go: defer resp.Body.Close()
# Java: try-with-resources7.3 场景三:高并发服务连接数审计
#!/bin/bash
# connection-audit.sh — 连接审计报告
echo "=== 连接审计报告 $(date) ==="
echo ""
echo "--- TCP 状态分布 ---"
ss -tan | awk 'NR>1 {s[$1]++} END {for(k in s) printf "%-15s %d\n", k, s[k]}' | sort -k2 -rn
echo ""
echo "--- Top 10 目标 IP (ESTABLISHED) ---"
ss -tan state established | awk 'NR>1 {split($5,a,":"); print a[1]}' | \
sort | uniq -c | sort -rn | head -10
echo ""
echo "--- Top 10 监听端口 ---"
ss -tlnp | awk 'NR>1 {print $4, $NF}' | sort -t: -k2 -n
echo ""
echo "--- conntrack 使用率 ---"
CURR=$(cat /proc/sys/net/netfilter/nf_conntrack_count 2>/dev/null || echo "N/A")
MAX=$(cat /proc/sys/net/netfilter/nf_conntrack_max 2>/dev/null || echo "N/A")
echo "当前: $CURR / 上限: $MAX"
echo ""
echo "--- 网卡错误统计 ---"
for iface in $(ip -br link show | awk '$2=="UP" {print $1}'); do
ERRORS=$(ip -s link show "$iface" | grep -A 1 "RX:" | tail -1 | awk '{print $3}')
DROPS=$(ip -s link show "$iface" | grep -A 1 "RX:" | tail -1 | awk '{print $4}')
echo "$iface: errors=$ERRORS drops=$DROPS"
done
echo ""
echo "--- TCP 重传率 ---"
nstat -s 2>/dev/null | grep -E "TcpRetransSegs|TcpOutSegs" | \
awk '{a[$1]=$2} END {
if(a["TcpOutSegs"]>0)
printf "重传率: %.4f%%\n", a["TcpRetransSegs"]*100/a["TcpOutSegs"]
}'八、ip monitor:实时网络事件监控
ip monitor
是一个被忽视的强大工具,它实时监听内核 netlink
事件,能捕获所有网络配置变化:
# 监控所有网络事件
ip monitor all
# 只监控路由变化
ip monitor route
# 只监控邻居(ARP)变化
ip monitor neigh
# 只监控接口状态变化
ip monitor link
# 只监控地址变化
ip monitor address输出示例:
[ROUTE] 10.0.2.0/24 via 10.0.1.1 dev eth0
[NEIGH] 10.0.1.100 dev eth0 lladdr aa:bb:cc:dd:ee:ff REACHABLE
[LINK] 3: eth1: <BROADCAST,MULTICAST> mtu 1500 state DOWN
[ADDR] 3: eth1 inet 10.0.3.50/24 scope global eth1
工程场景:当你怀疑路由在动态变化导致间歇性故障时,开一个
ip monitor route
持续跑,等待路由跳变的证据。在多网卡服务器上,ip monitor link
能捕获网卡 flapping(频繁上下线)。
8.1 自动化网络事件告警
#!/bin/bash
# net-event-alert.sh — 网络事件实时告警
ip monitor all | while read -r line; do
TS=$(date '+%Y-%m-%d %H:%M:%S')
case "$line" in
*"state DOWN"*)
echo "[$TS] ALERT: 接口 DOWN - $line"
;;
*"FAILED"*)
echo "[$TS] ALERT: ARP 解析失败 - $line"
;;
*"Deleted"*route*)
echo "[$TS] WARN: 路由删除 - $line"
;;
esac
done8.2 /proc/net/softnet_stat 深度解读
softnet_stat 是诊断网络包处理瓶颈的关键文件:
cat /proc/net/softnet_stat
# 00015a3c 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
# 0000f2a1 00000003 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001每行一个 CPU,前三列最重要:
| 列 | 含义 | 异常判断 |
|---|---|---|
| 第 1 列 | 处理的帧总数 | 各 CPU 应大致均衡 |
| 第 2 列 | 因 netdev_budget 用完而 drop 的帧 |
> 0 表示 CPU 忙不过来 |
| 第 3 列 | time_squeeze,因时间片用完而推迟处理 |
> 0 表示 softirq 处理不及时 |
# 友好格式输出
awk '{printf "CPU%d: processed=%d dropped=%d squeezed=%d\n",
NR-1, strtonum("0x"$1), strtonum("0x"$2), strtonum("0x"$3)}' \
/proc/net/softnet_stat如果第 2 列(dropped)持续增长,需要增大
netdev_budget:
# 默认值 300,高负载服务器可以增大
sysctl -w net.core.netdev_budget=600
sysctl -w net.core.netdev_budget_usecs=4000如果处理量集中在 CPU 0,说明需要配置 RPS/RFS 或调整中断亲和。
九、工具选择决策矩阵
| 你想做什么 | 首选工具 | 备选工具 | 说明 |
|---|---|---|---|
| 查看监听端口 | ss -tlnp |
netstat -tlnp |
ss 更快 |
| 查看所有连接 | ss -tan |
netstat -an |
连接数多时 ss 必选 |
| 连接状态分布 | ss -tan \| awk |
netstat -an |
脚本化处理 |
| TCP 内核参数 | ss -ti |
— | 独有功能 |
| 路由表 | ip route |
route -n |
ip 功能更全 |
| ARP 表 | ip neigh |
arp -n |
ip 支持 NDP |
| 接口状态 | ip -br link |
ifconfig |
ip 输出更简洁 |
| 连接跟踪 | conntrack -L |
/proc/net/nf_conntrack |
conntrack 有过滤 |
| 协议统计 | nstat -s |
netstat -s |
nstat 显示增量 |
| 实时监控 | conntrack -E |
ip monitor |
事件驱动 |
十、总结:工具链的正确使用姿势
ss 替代 netstat。在任何连接数超过 1000 的环境中,
ss的性能优势是决定性的。熟练掌握ss的状态过滤和地址过滤语法,它能在一条命令中完成你以前需要netstat | grep | awk三步才能做到的事。ip 替代 ifconfig/route/arp。
ip命令族是现代 Linux 网络管理的标准工具。-br(简洁模式)和-j(JSON 模式)让它既适合人眼阅读也适合脚本处理。conntrack 是高并发的必检项。如果你的服务处理大量短连接(> 10,000 连接/秒),conntrack 表满是第一个要排除的故障。记住检查
dmesg | grep nf_conntrack。nstat 比 netstat -s 更有用。
nstat的增量统计模式让你能快速发现”刚才发生了什么”,而不是”历史总量是多少”。排查间歇性问题时,开着nstat -n 5等待问题复现。/proc/net/ 是最底层的数据源。当高级工具都不够用时,直接读
/proc/net/snmp、/proc/net/netstat、/proc/net/softnet_stat。这些文件是内核的真实状态,没有任何中间层。
参考文献
- iproute2 documentation (man7.org/linux/man-pages/man8/ss.8.html)
- Linux kernel networking documentation (kernel.org/doc/html/latest/networking)
- Benvenuti, C. (2005). Understanding Linux Network Internals, O’Reilly Media
- nf_conntrack documentation (conntrack-tools.netfilter.org)
- Brendan Gregg (2020). Systems Performance, 2nd Edition, Addison-Wesley
下一篇:BPF 网络诊断:bpftrace 与 bcc 工具实战
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【网络工程】tcpdump 实战精通:BPF 过滤与捕获策略
系统讲解 tcpdump 的工程实战:BPF 过滤语法完整指南、滚动捕获策略、时间戳精度控制、容器/Pod 环境抓包、高级用法与性能优化,让抓包成为系统化的诊断方法。
【网络工程】网络故障排查系统化方法:从现象到根因
系统讲解网络故障排查的方法论:OSI 分层排查法、连通性/性能/间歇性三类故障的诊断路径、排查决策树、工具链选择、真实故障案例复盘,建立从'网络不通'到精确定位根因的工程能力。
【网络工程】BPF 网络诊断:bpftrace 与 bcc 工具实战
系统讲解 eBPF 在网络诊断中的工程应用:bcc 工具集(tcplife/tcpretrans/tcpdrop)的使用场景、bpftrace 自定义网络探针编写、XDP 丢包分析、内核协议栈延迟追踪,建立基于 eBPF 的系统化网络诊断方法。
【网络工程】L4 负载均衡:IPVS、LVS 与连接级调度
系统讲解 L4 负载均衡的内核实现:IPVS 的工作原理与三种转发模式(NAT/DR/TUN)、调度算法选择、LVS 高可用方案(Keepalived + VIP)、云环境中的 L4 LB(NLB/MetalLB),建立传输层负载均衡的工程能力。