top和htop看不到带宽占用进程,因其不统计网络I/O;真正瓶颈常在网络收发队列或内核协议栈,需用ss、iftop、tcpdump等工具定位发包/收包进程及连接堆积问题。

为什么 top 和 htop 看不到带宽占用进程
因为 top 默认只显示 CPU 和内存使用率,不统计网络 I/O。即使网卡跑满,top 里所有进程的 %CPU 可能都低于 10%,业务响应也正常——这说明瓶颈不在 CPU 或磁盘,而在网络收发队列或内核协议栈处理能力上。
真正要查的是:谁在持续发包?谁在大量收包?有没有连接堆积?
- 用
ss -ti查每个 TCP 连接的retrans(重传)、qsize(发送队列长度)、rcv_space(接收窗口) - 用
cat /proc/net/dev确认是rx还是tx满载;若rx满但应用没读包,Recv-Q会持续增长 -
iftop -P能按端口实时看流量归属,但需 root 权限,且默认不解析进程名(加-P后仍可能显示unknown,因部分流量走内核 bypass 路径如 XDP 或 AF_XDP)
netstat -s 里哪些字段暴露真实瓶颈
netstat -s 输出的是内核网络协议栈的统计,比进程级工具更接近真相。重点盯这几个字段:
-
TCP: packets received和packets to unknown port差值大 → 大量 SYN 包打到未监听端口(如被扫描或配置错端口) -
TCPSynRetrans高 → 客户端反复重发 SYN,可能是防火墙丢包、SYN Cookie 触发或后端服务未响应 -
tcpListenOverflows> 0 →net.core.somaxconn不够,新连接被丢弃,但已有连接不受影响,所以业务“看似正常” -
tcpBacklogDrop> 0 → accept 队列已满,新连接进不了用户态,但三次握手已完成,客户端以为连上了(造成假连接)
UDP 流量满带宽却查不到对应进程
UDP 无连接、无状态,内核不会为每个包维护连接上下文,ss -u 或 lsof -iUDP 只能列出“当前绑定端口”的进程,对发完就扔的 UDP 发送方(比如监控上报、日志采集、DNS 查询)完全不可见。
这时候得从包层面切入:
- 用
tcpdump -i eth0 -c 1000 udp and port not 53抓包,看源 IP/端口分布;如果大量来自同一本地端口,大概率是某个应用批量发 UDP -
cat /proc/net/udp查 UDP socket 绑定状态,注意st字段:07 表示 ESTABLISHED(仅对有连接语义的 UDP 封装有效),多数 UDP socket 是 01(RAW) - 检查
/etc/cron.d/或 systemd timer,有些日志轮转脚本会调用logger发 UDP 到127.0.0.1:514,而 rsyslog 若未启用$SystemMaxMessageSize限制,可能被大日志撑爆带宽
业务无异常但 softirq 占用高
执行 top 按 1 显示所有 CPU 核,再按 shift + H 切换线程视图,找 si(softirq)列持续 >80% 的核——这说明内核正在忙于处理网络中断和协议栈任务,但用户态进程还没被拖慢。
- 用
cat /proc/softirqs看NET_RX和NET_TX计数是否远高于其他项(比如高出 10 倍) - 检查网卡是否启用了
RSS(Receive Side Scaling):若只有单核处理所有 RX 中断,NET_RX会集中在某一个 CPU 上 - 确认是否开了
irqbalance,并检查ethtool -l eth0的 channel 数量是否匹配 CPU 核数;否则大量中断挤在 CPU0,softirq 成瓶颈,但业务进程调度不受直接影响
这种情况最易被忽略:带宽跑满不是因为业务逻辑在发数据,而是内核在替你“扛包”。一旦并发连接数再涨一点,或出现丢包重传,业务延迟就会突变。








