登录
首页 >  文章 >  python教程

Python监控网络流量\_psutil实现自动监控

时间:2026-04-03 11:18:25 245浏览 收藏

本文深入解析了如何用 psutil 准确监控 Python 中的实时网络流量,直击初学者常见误区:psutil.net_io_counters() 返回的是系统启动以来的累计字节数,而非瞬时速率;文章手把手教你通过两次采样、时间差计算(推荐使用 time.monotonic() 确保稳定性)、白名单过滤物理网卡(规避虚拟接口干扰)、以及针对 Windows 权限与性能计数器限制的健壮异常处理方案,帮你避开“画出直线上升曲线”“容器流量虚高”“Windows 下莫名报错”等典型坑,真正落地可运行、生产可用的网络流量监控逻辑。

Python监控系统网络流量数据_psutil实现流量自动化监控

psutil.net_io_counters() 返回的数值是累计值,不是实时速率

很多人一上来就用 psutil.net_io_counters() 每秒调一次,直接把 bytes_sent 当成“当前发送速度”,结果画出来的图是一条直线上升的线。它返回的是自系统启动以来的总字节数,不是每秒增量。

要算实时速率,必须自己做两次采样、相减、再除以时间间隔:

  • 至少间隔 0.5 秒以上采样,太短会导致浮点精度误差或归零(尤其低流量时)
  • 第一次采样后 sleep 1 秒,第二次再调用,用差值除以 1.0 才是近似 B/s
  • 别用 time.time() 做间隔基准——用 time.monotonic() 更稳,避免系统时间回拨干扰
import psutil, time
io1 = psutil.net_io_counters()
time.sleep(1)
io2 = psutil.net_io_counters()
speed_bps = (io2.bytes_sent - io1.bytes_sent) / 1.0

不同网卡接口的数据不能混着加总

一台服务器可能有 eth0docker0vethxxxxlo 多个接口,psutil.net_io_counters(pernic=True) 返回的是 dict,key 是接口名。直接对所有值求和会把 loopback 流量也算进去,导致监控值虚高 20%–50%(尤其容器密集环境)。

真实业务流量通常只走物理网卡或指定 bond 接口:

  • 先用 psutil.net_if_addrs() 过滤出有 IPv4 地址且非 lo 的接口名
  • 排除 veth*br-docker0 等虚拟接口(除非你明确要监控容器网络)
  • 生产环境建议配置白名单,比如只监控 ['ens192', 'bond0'],而不是动态枚举

Windows 下 net_io_counters() 可能返回空或 KeyError

Windows 上某些精简版系统、Hyper-V 虚拟机、或启用了“网络连接状态指示器”优化时,psutil.net_io_counters() 可能抛 KeyError: 'bytes_sent',或者返回的 dict 缺少关键字段。这不是 bug,是 Windows 性能计数器没启用或权限不足。

稳妥做法是加 fallback 和日志:

  • 捕获 KeyErrorRuntimeError,记录警告并跳过本次采集
  • 首次运行时检查 psutil.net_if_addrs() 是否能正常返回,判断基础网络信息是否可读
  • 避免在无管理员权限的 CMD 下运行——Windows 需要 SeNetworkStatisticsPrivilege 权限,普通用户可能拿不到完整数据

高频采集(

psutil.net_io_counters() 底层调用系统 API,Linux 走 /proc/net/dev,Windows 走 PDH,都不是零开销操作。实测在 2C4G 的云主机上,每 100ms 调一次,CPU 占用能到 8%–12%,远超预期。

监控节奏得按场景分档:

  • 告警级监控:2–5 秒采样一次足够,速率波动看趋势,不是抓瞬时峰值
  • 调试定位问题时才临时切到 200ms,并加 if __debug__: 包裹,上线前删掉
  • 如果用 asyncio,别在线程里反复调这个函数——它不是异步友好的,阻塞主线程

真要毫秒级观测,应该换 eBPF 或 libpcap 方案,psutil 不是干这个的

好了,本文到此结束,带大家了解了《Python监控网络流量\_psutil实现自动监控》,希望本文对你有所帮助!关注golang学习网公众号,给大家分享更多文章知识!

资料下载
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>