Linux网络性能问题核心是时延高、重传多、吞吐低,需通过ss -i、netstat -s、tcpretrans、dropwatch及ethtool -S等工具分层定位TCP重传、丢包位置、驱动级丢包和应用层队列瓶颈。

Linux 网络性能问题通常不是“连不上”,而是“时延高、重传多、吞吐上不去”——直接看 ifconfig 或 ip addr 没用,得盯住内核网络栈真实行为。
怎么看 TCP 重传和连接异常?用 ss -i 和 netstat -s
ss -i 能实时显示每个 socket 的重传计数、RTT、拥塞窗口等,比 netstat 更轻量且准确;netstat -s 则汇总了全系统 TCP 层统计,重点看这几行:
-
TCPRetransSegs:已重传的 TCP 段数,持续增长说明链路丢包或接收端处理不过来 -
TCPTimeouts:超时重传次数,若远高于TCPRetransSegs,可能是 RTO 设置过激或 RTT 波动极大 -
TCPSpuriousRtx:虚假重传(非丢包触发),常见于时间戳未开启或接收端延迟 ACK 过久
运行 netstat -s | grep -i -E "retrans|timeout|spurious" 可快速过滤。注意:CentOS 7+ 默认禁用 netstat,需装 net-tools 包;推荐优先用 ss -s(但不显示重传细节)。
丢包发生在哪一层?用 tcpretrans 和 dropwatch 定位
用户常误以为丢包=网卡问题,其实可能在 IP 层(如 ip_forward 关闭)、iptables 规则(REJECT 不计为 drop)、甚至 socket 接收队列溢出(Recv-Q 持续满)。
-
tcpretrans(来自 bcc 工具集)可追踪每个重传事件的源头 socket 和调用栈,需启用 ftrace 和 kernel debuginfo -
dropwatch -d -l kas监听内核 drop 点,输出类似skb_drop: 10.244.1.5:48922 10.244.1.6:80 (tcp),能定位到具体协议栈函数(如tcp_v4_do_rcv、ip_local_deliver) - 若
dropwatch显示大量nf_hook_slow,大概率是 iptables/nftables 规则匹配耗时或丢弃
没有 bcc?可用 cat /proc/net/snmp | grep -A1 Tcp 查看 EstabResets(异常关闭)和 AttemptFails(SYN 发出后无响应),辅助判断是服务未启还是中间拦截。
ethtool -S 输出里哪些字段真有用?
ethtool -S eth0 返回上百行计数器,多数与物理层相关,但只有几个对排查真实网络性能关键:
-
rx_discards:驱动层丢包,值 > 0 且持续增长 → 接收队列满(net.core.netdev_max_backlog不足)或内存不足 -
rx_missed_errors:DMA 未及时取走数据导致 ring buffer 溢出,和rx_discards同时升高 → CPU 处理不过来或中断绑定不均 -
tx_aborted_errors/tx_carrier_errors:物理链路问题(网线、光模块、交换机端口协商失败),非软件可调 - 避开干扰项:
rx_crc_errors在千兆以上网卡中极少由真实 CRC 错误引起,更多是 DMA 边界错位,不必优先排查
注意:不同网卡驱动暴露的字段名差异大(如 ixgbe 用 rx_discards,igb 用 rx_dropped),务必查对应驱动文档。
为什么 ping 延迟低,但应用 HTTP 却卡顿?看 socket 队列和 TIME_WAIT
ping 测的是 ICMP echo,绕过传输层和应用层缓冲;而 HTTP 卡顿往往卡在:
- 发送端
Send-Q持续 > 0(ss -tni查看),说明应用 write() 后内核发不出去 → 拥塞控制压制、对端接收窗口为 0、或网卡 TX queue 堵塞 - 大量
TIME-WAITsocket 占满本地端口(尤其短连接服务),表现为connect(): Cannot assign requested address→ 调整net.ipv4.ip_local_port_range和net.ipv4.tcp_fin_timeout,但更优解是复用连接或改用net.ipv4.tcp_tw_reuse = 1(仅客户端有效) -
ss -lnt显示监听端口Recv-Q长期 > 0 → 应用 accept() 太慢,或被信号/锁阻塞
别迷信 iftop 或 nethogs 显示的“实时流量”,它们基于 pcap 抓包,本身会引入延迟且无法反映队列堆积。真正瓶颈往往藏在 ss -i 的 cwnd、rtt、retrans 字段里。









