服务器如何监控网络带宽使用情况?实时流量统计与异常分析

月底收到云厂商账单,流量费比上个月翻了三倍;或者用户反馈晚上八点网站特别卡,但 CPU 和内存都很空闲。这两种情况的元凶往往都是网络带宽。带宽问题的麻烦之处在于它"看不见"——CPU 有 top、磁盘有 df,而网络流量需要专门的工具才能观测,而且单位换算(bit 与 Byte)极易搞错,导致对着 8 MB/s 的数值以为自己把 100 Mbps 带宽跑满了八倍。本文讲清楚 Linux 服务器上监控网络带宽的完整方法:从单位换算这个基础认知讲起,到实时流量工具(nload、iftop、sar、ip -s link)、历史统计(vnstat)、按进程定位(nethogs),再到 Prometheus 长期监控与异常分析思路。

一、先搞对单位:8 倍误差就从这来

这是网络监控第一道坎,也是最容易闹笑话的地方。运营商和云厂商说的带宽是 bit(比特),而 Linux 系统工具显示的通常是 Byte(字节),1 Byte = 8 bit。

  • 购买带宽 1 Mbps = 1,000,000 bit/s ÷ 8 = 125 KB/s 的理论最大下载速度
  • 购买带宽 10 Mbps ≈ 1.25 MB/s
  • 购买带宽 100 Mbps ≈ 12.5 MB/s
  • 购买带宽 1 Gbps ≈ 125 MB/s

所以当你看到 iftop 显示 12.5MB 而带宽是 100Mbps 时,带宽已经跑满了。反过来,如果工具显示 KB/s 而你的带宽是 100 Mbps,把 KB/s 数值乘以 8 再除以 1000 就是 Mbps 占用。另外要注意:云服务器的"带宽"通常指出方向(上行)限速,入方向(下行)往往不限速或限速更宽松——网站服务主要消耗出方向带宽,所以看流量要重点看出方向(TX)。

工具显示单位看实时/历史能否按连接/进程安装
nloadByte/s(可切换 bit)实时否yum/apt install nload
iftopByte/s实时按连接(IP:端口)yum/apt install iftop
ip -s link累计 Byte累计值否系统自带(iproute2)
sar -n DEVByte/s、包/s实时 + 历史否sysstat 包
vnstatByte(汇总)历史(按天/月)否yum/apt install vnstat
nethogsKB/s实时按进程yum/apt install nethogs

二、实时流量:四款工具怎么用

2.1 nload:一眼看全貌,最适合日常巡检

nload 的界面分上下两块:上半部是入方向(Incoming),下半部是出方向(Outgoing),实时显示当前速率(Curr)、平均值(Avg)、最小值(Min)、最大值(Max)和累计流量(Ttl)。它最大的优点是直观——连上服务器敲 nload,两秒就能判断"现在带宽跑了多少"。

# 安装
yum install -y nload        # 需 EPEL 源
apt-get install -y nload

# 查看默认网卡
nload

# 指定网卡(多网卡机器必须指定)
nload eth0

# 切换单位显示:运行后按 u 键,在 Bit/s、Byte/s、kBit/s 等之间切换
# 按 m 键切换显示模式,按 q 退出

# 只看总流量不做交互,配合 -t 指定刷新间隔(毫秒)
nload -t 1000 eth0

2.2 iftop:看"谁"在占带宽

当 nload 告诉你带宽跑满了,下一步要知道是哪些连接在消耗。iftop 就是干这个的,它按连接(源 IP:端口 ↔ 目标 IP:端口)实时排序展示速率,是排查异常流量的第一利器。

# 安装与启动
yum install -y iftop
iftop -i eth0

# 常用参数
iftop -i eth0 -n          # -n 不做 DNS 反解析,避免解析拖慢显示(强烈建议加)
iftop -i eth0 -N          # -N 显示端口号而非服务名
iftop -i eth0 -P          # -P 显示端口,最常用组合:iftop -i eth0 -nP
iftop -i eth0 -F 10.0.0.0/24   # 只统计指定网段的流量
iftop -i eth0 -B          # 以 Byte 为单位显示(默认是 bit)

# 交互式按键(运行时按)
# P  暂停/继续刷新
# T  切换是否显示每条连接的累计流量
# s  按源地址排序 / d 按目标地址排序
# < 或 >  按源或目标端口排序
# L  切换显示刻度尺

iftop 顶部有一个刻度尺,最右端的数值代表当前满刻度速率,底部三行分别是 2 秒、10 秒、40 秒的平均流量(cum 是自启动以来的累计值)。判读要点:看最上面几行是哪些 IP 占了大头;如果某个 IP 的流量远超其他,且它不在你的业务预期之内,八成是异常(爬虫、盗链、扫描、被当肉鸡)。注意默认显示是 bit/s,加 -B 才是 Byte/s。

2.3 ip -s link 与 sar -n DEV:脚本友好、能进监控

交互工具适合人看,但要写脚本或做长期采集,需要文本输出的工具。

# 查看网卡累计收发统计(RX 收、TX 发),注意这是自开机/重置以来的累计值
ip -s link show eth0

# 只看关键几行
ip -s link show eth0 | awk '/RX:/{getline; print "接收:", $1} /TX:/{getline; print "发送:", $1}'

# 每秒刷新一次,看增量(sar 来自 sysstat)
sar -n DEV 1

# 看错误与丢包(关键!rxdrop/txdrop 非 0 说明网卡缓冲溢出)
sar -n EDEV 1

# 看历史(sysstat 每 10 分钟采集一次,保留 7-30 天)
sar -n DEV -f /var/log/sa/sa15      # 查看 15 号的数据

# 手动算 5 秒平均速率(/proc/net/dev 第 1 列是接收字节,第 9 列是发送字节)
get_rx() { awk '/eth0:/{print $1}' /proc/net/dev; }
get_tx() { awk '/eth0:/{print $9}' /proc/net/dev; }
r1=$(get_rx); t1=$(get_tx); sleep 5; r2=$(get_rx); t2=$(get_tx)
echo "接收: $(( (r2-r1)/5 )) B/s    发送: $(( (t2-t1)/5 )) B/s"

sar -n DEV 1 的输出列:IFACE 网卡名、rxpck/s 每秒收包数、txpck/s 每秒发包数、rxkB/s 每秒接收千字节、txkB/s 每秒发送千字节、rxcmp/s/txcmp/s 压缩包、rxmcst/s 每秒多播包。把 rxkB/s 和 txkB/s 乘以 8 再除以 1024,就得到 Mbps。而 sar -n EDEV 里的 rxdrop/s、txdrop/s、rxerr/s、rxfram/s 一旦长期非 0,说明存在丢包,可能原因包括带宽跑满、网卡 Ring Buffer 不足、网线或交换机端口故障。

# 查看网卡层面的丢包与错误计数(ethtool)
ethtool -S eth0 | grep -Ei 'drop|error|miss|fifo'
ethtool eth0 | grep -E 'Speed|Link detected'      # 确认协商速率与链路状态

三、历史统计:vnstat 按月/天看用量

实时工具看不到"这个月用了多少流量",而这与计费直接相关。vnstat 是一个极轻量的守护进程,后台持续记录每个网卡的收发总量,能按小时、天、月、年出报表,几乎不占资源。

# 安装并启动
yum install -y vnstat     # 或 apt install vnstat
systemctl enable --now vnstat

# 初始化要监控的网卡(必须先建库)
vnstat -i eth0 --add
# 如提示数据库不存在,执行:
vnstat -u -i eth0

# 查看报表
vnstat                    # 默认显示日/月汇总
vnstat -d                 # 按天
vnstat -m                 # 按月,看月度总流量
vnstat -h                 # 按小时,定位每天的高峰时段
vnstat -t                 # 显示流量 Top 10 天

# 实时模式(类似 nload 的效果)
vnstat -l -i eth0

# JSON 输出,方便脚本接入
vnstat --json

vnstat -h 的输出特别适合定位业务高峰:如果发现每天 20:00-22:00 流量是平时的 5 倍,那这个时段就是带宽规划的依据。vnstat -m 用于月度对账,与云厂商账单比对能发现流量异常。

四、按进程定位:nethogs

知道带宽跑满、知道对端 IP 之后,还想知道"本机哪个进程造成的",用 nethogs。它按进程(PID + 程序名)分组显示实时速率,是定位"不知名进程偷跑流量"的终极工具。

# 安装与使用(需要 root)
yum install -y nethogs
nethogs eth0

# 指定刷新间隔(秒),默认 1 秒
nethogs -d 5 eth0

# 只看某几个进程 / 以 KB/s 显示
nethogs -v 3 eth0

# 交互式按键
# m  在 KB/s、KB、B、MB 之间切换单位
# r  按接收速率排序
# s  按发送速率排序
# q  退出

常见发现:某个 Java 进程持续对外发送大量数据(可能是日志采集配置错误)、某个 rsync/wget 后台任务在同步大文件、某个被植入的挖矿程序在对外通信。定位到 PID 后用 ls -l /proc/PID/exe 和 cat /proc/PID/cmdline 确认进程来源。

五、长期监控与告警:Prometheus 方案

交互工具解决"现在怎么了",长期监控解决"趋势如何、何时该扩容"。node_exporter 提供网卡收发字节的 Counter 指标,用 rate() 换算成每秒速率。

# 出方向带宽速率(字节/秒),排除 lo 与容器虚拟网卡
rate(node_network_transmit_bytes_total{device!~"lo|veth.*|docker.*|br-.*"}[5m])

# 入方向带宽速率
rate(node_network_receive_bytes_total{device!~"lo|veth.*|docker.*|br-.*"}[5m])

# 换算成 Mbps(字节 × 8 ÷ 1000000)
rate(node_network_transmit_bytes_total{device="eth0"}[5m]) * 8 / 1000000

# 带宽占用百分比(假设购买带宽 100 Mbps,写在 Grafana 变量里更好)
rate(node_network_transmit_bytes_total{device="eth0"}[5m]) * 8 / 1000000 / 100 * 100

# 网卡错误与丢包速率
rate(node_network_receive_drop_total{device="eth0"}[5m])
rate(node_network_transmit_drop_total{device="eth0"}[5m])

# TCP 重传率
rate(node_netstat_Tcp_RetransSegs[5m])

告警规则建议按占用百分比分级:出方向带宽占用持续超过 70% 达 10 分钟发预警(说明需要关注),超过 90% 持续 5 分钟发严重告警(已接近瓶颈,用户会感知卡顿)。另外强烈建议对"月度累计流量"单独设一条预警:云厂商按流量计费时,月中流量已达上月 80% 就该提醒,避免月底账单惊吓。

六、异常分析思路

看到流量异常时,按下面这张判定表逐条对照,能快速收敛范围。

现象可能原因验证方式处理方向
出带宽持续跑满业务增长 / 盗链 / 爬虫iftop 看 Top IP,Nginx 日志统计 UA限速、防盗链、封 IP、扩容
夜间突发大流量备份任务 / 定时同步比对 cron 时间与 vnstat -h调整到低峰、限速
入流量异常高被攻击 / 上传业务 / 日志回传iftop 看来源 IP 集中度接入防护、限流
丢包 rxdrop 非 0带宽满 / Ring Buffer 小ethtool -S 看 fifo/dropethtool -G 调大缓冲
重传率高网络质量差 / 跨运营商ss -i 看 retrans,mtr 查链路换线路、上 CDN
单 IP 连接数极高CC 攻击 / 客户端 bugss -ant 按 IP 统计iptables/ngx 限流
# 统计当前各 IP 的 TCP 连接数,找出异常来源
ss -ant | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head -20

# 统计 Nginx 日志里访问量最高的 IP(找出爬虫或盗链)
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -20

# 统计消耗流量最多的 URL(按 body_bytes_sent 求和)
awk '{sum[$7]+=$10} END {for(u in sum) print sum[u], u}' /var/log/nginx/access.log \
  | sort -nr | head -20

# 查链路质量,定位丢包发生在哪一跳
mtr -r -c 100 8.8.8.8

七、排查与建设步骤

  1. 确认基础信息:用 ethtool eth0 看协商速率(是 1000Mb/s 还是 100Mb/s),向云厂商确认购买带宽数值与计费方式(按带宽还是按流量)。
  2. 装好三件套:nload(看全貌)、iftop(看连接)、vnstat(看历史),并启动 vnstat 守护进程建库。
  3. 跑 nload eth0 观察 1 分钟,记录业务高峰期的出方向速率,换算成 Mbps 与购买带宽对比。
  4. 用 vnstat -h 找出每天的高峰时段,用 vnstat -m 确认月度用量。
  5. 若发现跑满,用 iftop -nP 找出 Top 连接,再用 nethogs 定位到进程。
  6. 用 sar -n EDEV 1 与 ethtool -S 检查是否存在丢包,有则排查缓冲与链路。
  7. 接入 Prometheus 做长期曲线,配置 70% 预警、90% 严重告警,以及月度流量用量提醒。
  8. 每月做一次流量对账:vnstat 月报与云厂商账单比对,偏差超过 10% 要查原因。

小结

服务器网络带宽监控的工具链很清晰:nload 看整体占用、iftop 看连接明细、nethogs 看进程、vnstat 看历史账单、sar -n DEV 与 ip -s link 做脚本采集、Prometheus 做长期趋势与告警。上手前务必把单位换算搞清楚——系统工具多为 Byte/s,云厂商带宽是 bit/s,1 Mbps 对应 125 KB/s。告警阈值建议按占用百分比设:70% 预警、90% 严重。避坑清单:一是把 MB/s 当 Mbps 导致 8 倍误判;二是只看出方向忽略入方向(虽然云服务器主要限制出方向);三是 iftop 不加 -n 导致 DNS 反解析拖慢甚至卡住界面;四是只看实时不看历史,错过夜间突发的备份流量;五是忘了看丢包与重传指标,带宽没满但用户体验依然很差——这时候问题在链路质量而不在带宽容量。把这几项补齐,带宽问题就能从"月底才发现"变成"当天就定位"。


关键词:网络带宽监控、iftop、nload、vnstat、sar -n DEV、流量异常分析