这是《Linux 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 Linux 网络栈从网卡收包开始,经过中断、软中断、协议栈、socket、进程读写,再到路由和发包。应用网络慢可能是协议问题,也可能是丢包、队列、conntrack、CPU 或缓冲区问题。
18.1 收发包路径
NIC
-> DMA / Ring Buffer
-> Hard IRQ
-> Soft IRQ
-> IP / TCP / UDP
-> Socket Receive Queue
-> Application read
发包:
Application write
-> Socket Send Buffer
-> TCP / IP
-> QDisc
-> NIC Ring
-> Send
18.2 基础命令
地址与路由:
ip -br addr
ip route
ip -s link
ethtool eth0
ethtool -S eth0
连接:
ss -s
ss -antp
ss -lntp
ss -ti
ss -m
统计:
netstat -s
nstat -az
cat /proc/net/softnet_stat
cat /proc/net/snmp
18.3 网卡统计
ethtool -S eth0 | grep -Ei 'drop|err|fifo|miss|overflow'
ip -s link show eth0
常见字段:
| 指标 | 含义 |
|---|---|
| rx_dropped | 採收丢弃 |
| tx_dropped | 发送丢弃 |
| rx_errors | 接收错误 |
| tx_errors | 发送错误 |
| rx_missed | Ring Buffer 缺失 |
| rx_no_buffer | 缓冲不足 |
不同网卡驱动字段名称可能不同。要关注持续增长值,而不是只看单次累计值。
18.4 软中断
查看:
mpstat -P ALL 1
cat /proc/interrupts
cat /proc/net/softnet_stat
watch -n1 'cat /proc/softirqs'
softnet 第二列丢弃:
cat /proc/net/softnet_stat
处理方向:
- 开启 RSS / 多队列;
- 调整队列亲和;
- 增加缓冲;
- 降低单 CPU 中断压力;
- 扩容或限流。
18.5 Ring Buffer 与队列
查看:
ethtool -g eth0
ethtool -l eth0
ethtool -x eth0
调整:
sudo ethtool -G eth0 rx 4096 tx 4096
RSS:
cat /proc/irq/<irq>/smp_affinity_list
echo 2 | sudo tee /proc/irq/<irq>/smp_affinity_list
增大缓冲会增加内存和排队延迟,必须结合延迟指标评估。
18.6 TCP 缓冲与拥塞
查看:
ss -ti
ss -m
sysctl net.core.rmem_max
sysctl net.core.wmem_max
sysctl net.ipv4.tcp_rmem
sysctl net.ipv4.tcp_wmem
sysctl net.ipv4.tcp_congestion_control
关键观察:
| 字段 | 含义 |
|---|---|
| cwnd | 拥塞窗口 |
| ssthresh | 慢启动阈值 |
| retrans | 重传 |
| rto | 重传超时 |
| rtt | 往返时间 |
| Send-Q / Recv-Q | socket 队列 |
网络参数优化必须基于路径 RTT、丢包率和吞吐目标,不能照抄所谓万能参数。
18.7 防火墙与 conntrack
查看:
sudo iptables -L -n -v
sudo nft list ruleset
sudo conntrack -S
sudo conntrack -C
sysctl net.netfilter.nf_conntrack_max
表满时新建连接可能失败:
dmesg -T | grep -i conntrack
处理:
- 监控使用率;
- 评估表上限;
- 缩短不合理超时;
- 优化规则顺序;
- 控制短连接风暴。
18.8 Loopback 与本地通信
ip addr show lo
ss -lntup
curl -v http://127.0.0.1:8080/healthz
本地通信仍会经过协议栈和 socket。排查时可用:
sudo tcpdump -i lo -nn port 8080
strace -e trace=network -p <pid>
18.9 eBPF 与高级观测
常用工具:
| 工具 | 场景 |
|---|---|
tcpretrans |
TCP 重传 |
tcplife |
连接生命周期 |
tcpconnect |
主动连接 |
tcpaccept |
被动连接 |
biolatency |
IO 延迟 |
execsnoop |
新进程 |
opensnoop |
文件打开 |
安装:
sudo apt install bpfcc-tools
sudo dnf install bcc-tools
工具名在不同包中可能带 -bpfcc 后缀。
18.10 常见故障
丢包
ip -s link show eth0
ethtool -S eth0
cat /proc/net/softnet_stat
nstat -az | grep -Ei 'drop|err'
定位层次:
网卡 / 驱动
-> softirq
-> conntrack / firewall
-> socket buffer
-> application
连接队列溢出
ss -lnt
netstat -s | grep -Ei 'listen|overflow'
sysctl net.core.somaxconn
sysctl net.ipv4.tcp_max_syn_backlog
处理:
- 增大应用 accept backlog;
- 调整系统 backlog;
- 优化应用 accept 速度;
- 扩容。
重传高
nstat -az | grep -i retrans
ss -ti
mtr -rwzc 100 <peer>
区分本机丢包、路径丢包和对端处理慢。
本章小结
Linux 网络栈排障要沿收发包路径分层:网卡、中断、协议栈、conntrack、socket 和应用。ethtool 看设备层,ss 看连接和缓冲,netstat / nstat 看协议统计,tcpdump 和 eBPF 提供证据。调优前必须先定位丢包和队列瓶颈。
思考题
- 硬中断和软中断分别做什么?
rx_dropped和Listen Overflows有什么区别?- Ring Buffer 增大会带来什么权衡?
- conntrack 表满会表现为什么?
- 如何证明一次重传发生在本机、路径还是对端?