做资源监控面板时,大部分指标都好办:top/ps 拿 CPU 和内存,df 拿磁盘。唯独每个进程的实时网速(下行/上行) 没有现成的标准答案。
iftop 只到 IP 级别,nload/bmon 只有网卡级。要看"到底是哪个进程在跑流量",主流方案就一个:nethogs。
nethogs 默认是个交互式 TUI,做采集不能直接用。好在它有文本模式:
nethogs -t -c 3 -d 1
-t 文本输出(tracelog 模式)-c 3 采集 3 轮后退出-d 1 每轮间隔 1 秒程序化采集的关键就是 -c 控制轮数,不然进程永远不退出。
实际对接时发现,不同发行版仓库里的 nethogs 版本差异非常大,而 -t 的输出格式两个版本完全不兼容:
0.8.7 风格——字段间用竖线/斜杠分隔,PID 在倒数第二个斜杠段后面:
Refreshing:
unknown/1234/0/0/eth0/0 0 0
unknown/1234/0/0/eth0/0 12.5 3.2后面两列是先发送、后接收(KB/s),且数值是本轮速率。
0.8.5 风格——表头 + 空格对齐列,程序名可以含空格,PID 甚至可能是 ?:
PID USER PROGRAM DEV SENT RECEIVED
1234 root /usr/bin/python3 eth0 12.5 3.2 45.2 KB/sec解析器必须两套都认:先探测有没有表头行(PID USER PROGRAM),有就走 0.8.5 的按列切分,没有就走 0.8.7 的分隔符切分。另外 0.8.7 的数值有版本给的是累计值而不是速率,要做差才能得到本轮网速——这点文档里完全没写,只能拿真实输出核对。
nethogs 需要抓包权限,非 root 运行时看不到其他用户进程的流量归属,socket 信息是空的。这是内核行为,不是 bug。做 UI 时要如实显示"无归属",不要拿 0 充数,不然用户会以为真的没流量。
排查过程中还发现一个常见误区:很多人拿 ss -tainp 拿连接列表,然后纳闷 UDP 连接怎么一直是空的——因为 -t 就是 TCP-only。要 TCP + UDP 全拿,得用:
ss -tuainp-u 加上才有 UDP。另外输出里本地地址可能带 %lo 这类 zone 标记,解析时记得清掉,不然字符串比对会阴差阳错。
不同发行版装法还不一样,收集了一下:
# Debian / Ubuntu
apt install nethogs
# CentOS 7(需要先装 EPEL)
yum install epel-release && yum install nethogs
# CentOS 8+ / RHEL 系
dnf install nethogs
# Alpine
apk add nethogs做产品的话,探测到没装时应该按发行版把具体命令拼好给用户,而不是甩一句"请安装 nethogs"。
-t -c N -d 1ss -tuainp,-t 单用会漏 UDP这些都是拿真实机器的输出一条条核对出来的,希望能帮到做类似面板的同学。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。