本文目录导读:

从原理到自动化部署
目录导读
- 为什么需要带宽占用统计脚本?
- 带宽统计的核心原理与数据类型
- 主流实现方案对比(Python/Shell/Go)
- 手把手编写一个可用的带宽监控脚本
- 数据存储与可视化方案
- 常见问题与性能优化问答
- 总结与自动化部署建议
为什么需要带宽占用统计脚本?
在服务器运维、网络管理或家庭路由器监控中,带宽占用数据是排查网络瓶颈、优化流量分配的关键依据,许多网络管理员会发现:默认的 iftop 或 nload 工具只能实时查看,无法长期记录,而商业监控软件(如 SolarWinds)价格高昂,且依赖特定协议。
场景案例:某公司内网频繁卡顿,管理员发现一台 Linux 服务器在凌晨 3 点持续上传大量数据,通过编写一个带宽统计脚本,成功定位到是备份任务超时触发了重传机制,节约了 30% 的带宽成本。
核心需求:
- 按进程、端口、IP 汇总带宽
- 支持历史数据查询
- 低资源消耗(不干扰业务)
- 可集成到现有监控平台
带宽统计的核心原理与数据类型
1 数据来源
- /proc/net/dev:Linux 内核提供的设备级流量计数器(字节数)
- netstat / ss:显示当前连接状态和字节数
- tcpdump / nfconntrack:抓取实时数据包(精度高但开销大)
- libpcap:程序化抓包(适合自定义协议分析)
2 关键指标
| 指标 | 单位 | 说明 |
|---|---|---|
| RX bytes | 字节 | 接收总流量 |
| TX bytes | 字节 | 发送总流量 |
| RX packets | 包数 | 接收数据包数量 |
| TX packets | 包数 | 发送数据包数量 |
| 瞬时速率 | bps | 每秒字节数 = (当前值 - 上次值)/时间差 |
3 时间维度
- 实时:秒级刷新(用于告警)
- 周期:5分钟/1小时聚合(用于容量规划)
- 长期:日/周/月趋势(用于预算审计)
主流实现方案对比
| 方案 | 语言 | 优势 | 劣势 |
|---|---|---|---|
| 系统命令+Shell | Bash | 零依赖,快速验证 | 解析复杂,跨版本兼容差 |
| Python + psutil | Python | 跨平台,丰富的网络接口 | 需Python环境 |
| Go + gopacket | Go | 高性能,二进制部署 | 学习曲线陡 |
| eBPF | C | 内核级,极低开销 | 内核版本要求高 |
推荐选择:对于大多数运维场景,Python + psutil 是最平衡的方案,如果只需要监控单机带宽总量,Shell + awk 完全够用。
手把手编写一个可用的带宽监控脚本
1 基础版:统计指定接口的实时带宽
#!/bin/bash
INTERFACE="eth0"
last_rx=$(cat /sys/class/net/$INTERFACE/statistics/rx_bytes)
last_tx=$(cat /sys/class/net/$INTERFACE/statistics/tx_bytes)
while true; do
sleep 1
current_rx=$(cat /sys/class/net/$INTERFACE/statistics/rx_bytes)
current_tx=$(cat /sys/class/net/$INTERFACE/statistics/tx_bytes)
rx_speed=$(( ($current_rx - $last_rx) / 1024 ))
tx_speed=$(( ($current_tx - $last_tx) / 1024 ))
echo "RX: ${rx_speed} KB/s | TX: ${tx_speed} KB/s"
last_rx=$current_rx
last_tx=$current_tx
done
2 进阶版:Python脚本统计进程级带宽
import psutil
import time
import csv
def get_network_usage():
"""监控每个进程的带宽消耗"""
connections = psutil.net_connections()
process_io = {}
for conn in connections:
pid = conn.pid
if pid and pid in psutil.pids():
io_counters = psutil.Process(pid).io_counters()
process_io[pid] = {
'read_bytes': io_counters.read_bytes,
'write_bytes': io_counters.write_bytes,
'name': psutil.Process(pid).name()
}
return process_io
# 初始化
prev_data = get_network_usage()
with open('bandwidth_log.csv', 'a', newline='') as f:
writer = csv.writer(f)
writer.writerow(['timestamp', 'pid', 'process', 'speed_kbps'])
for _ in range(60): # 监控60秒
time.sleep(5)
current_data = get_network_usage()
for pid, cur in current_data.items():
if pid in prev_data:
prev = prev_data[pid]
diff_read = cur['read_bytes'] - prev['read_bytes']
diff_write = cur['write_bytes'] - prev['write_bytes']
speed = (diff_read + diff_write) / 5120 # 转换为KB/s
writer.writerow([time.time(), pid, cur['name'], round(speed, 2)])
prev_data = current_data
3 部署注意事项
- 使用
nohup python3 bandwidth_monitor.py &后台运行 - 通过 crontab 设置定时重启(避免内存泄漏)
- 设置日志轮转(logrotate 管理 CSV 文件大小)
数据存储与可视化方案
1 存储层
| 方案 | 适用场景 | 示例命令 |
|---|---|---|
| CSV文件 | 小型环境 | 直接追加写入 |
| SQLite | 单机检索 | INSERT INTO traffic VALUES (?,?,?) |
| InfluxDB | 时序数据 | 使用 Telegraf 采集 |
| Prometheus | 大型集群 | 配置 node_exporter 的 textfile 收集器 |
2 可视化层
- Grafana:连接 InfluxDB,创建带宽仪表盘,支持单位自动转换(KB/s -> MB/s)
- 自建Web:Flask + Chart.js 显示最近24小时趋势
- 命令行输出:将结果通过
slack-cli发送到工作群
真实案例:某电商团队用 Python 脚本每10秒采集一次,存入 InfluxDB,Grafana 上设置带宽超过 80% 时触发 PagerDuty 告警,成功在DDoS攻击时提前切断。
常见问题与性能优化问答
Q1:脚本运行时CPU占用过高怎么办?
A:使用 psutil 监控时注意采样间隔不要低于1秒,并且只采集需要的进程,或者改用 /proc/net/dev 总流量统计,其CPU消耗几乎为零。
Q2:如何避免统计被重置(如网卡重启)?
A:在每次读取 /sys/class/net/eth0/statistics/rx_bytes 时,如果发现当前值小于上一次值,说明计数器归零,此时应重置起始点,而不是计算负数差值。
Q3:统计到 0 值怎么排查?
A:检查网卡名是否正确(可通过 ip link show 查看),确认脚本是否有 root 权限(/proc 下的部分文件需要 root)。psutil.net_connections() 需要以 root 运行才能获取全部连接。
Q4:需要统计虚拟机内部带宽怎么办?
A:在宿主机层面统计 vnet 虚拟网卡更精确,或者在虚拟机内部也部署一个脚本,最终由集中日志服务汇总。
Q5:如何实现按IP地址统计?
A:使用 tcpdump -i eth0 -nn 实时抓包,或通过 conntrack -L 读取连接状态表,更高效的方法是使用 iptables 的 -j LOG 规则,但会稍微影响转发性能。
总结与自动化部署建议
核心要点:
- 选择与场景匹配的方案:简单监控用 Shell,详细分析用 Python
- 必须设置采样间隔和日志轮转策略
- 结合 grafana 或 zabbix 实现可视化告警
自动化部署步骤:
- 将脚本和配置文件打包为 systemd service
- 使用 Ansible 批量下发到服务器
- 在 Grafana 导入预置的带宽仪表盘模板
延伸建议:
- 如果管理超过100台机器,需要考虑集中式日志收集(如 ELK Stack)
- 对于高速网络(10Gbps以上),考虑使用 DPDK 或 ebpf 减少上下文切换
最后提醒:不要仅依赖单一指标,结合 CPU、连接数、丢包率综合判断网络健康状态,带宽统计脚本是运维工具箱里的一把利刃,用好了能大幅提升故障排查效率。
本文结合实际运维经验,梳理了从原理到代码实现的完整路径,读者可根据自己的环境选取对应章节进行实践。