Pyshark持续嗅探模式下的数据包积压机制与风险问询
问题:Pyshark实时嗅探时数据包积压的行为与风险
背景
我原本的项目流程是先用Wireshark捕获.pcapng文件,再用Python的Pyshark包分析后存入Postgres数据库。现在想改成持续嗅探+实时分析的架构,替代原先的先捕获后处理模式。
核心疑问
- 当分析代码(结构较混乱)处理速度跟不上数据包流入速度时,Pyshark会出现什么情况?
- 不理解
sniff_continuously()的生成器实现逻辑(对生成器概念也没完全搞懂),想知道积压的数据包存在哪里——是内存、磁盘,还是会被传递/丢弃? - 如果数据包存在内存里,超出可用内存会有什么后果?还有哪些需要注意的事项?
测试情况
我跑了一个快速脚本,用Pyshark持续嗅探以太网的所有数据包,打印当前机器时间、数据包嗅探时间和内存占用,还加了延迟来刻意制造数据包积压。
从测试结果来看,Pyshark没有丢弃数据包(机器时间推进时,数据包嗅探时间只小幅递增),所以我猜测嗅探到的数据包被存在了某个地方。另外滚动平均内存占用有轻微增长,是不是确实是内存存储导致的?
测试代码:
import os, psutil, pyshark, time from datetime import datetime process = psutil.Process() capture = pyshark.LiveCapture(interface='Ethernet') print('Current Machine Time, Packet Sniff Time, Memory Utilized') for packet in capture.sniff_continuously(): print(f'{time.time()}, {datetime.fromtimestamp(float(packet.sniff_timestamp))}, {process.memory_info().rss}') # 单位:字节 time.sleep(5)
解答
1. sniff_continuously()的生成器逻辑与数据包存储
Pyshark的sniff_continuously()本质是基于子进程的异步捕获+生成器输出:
- 它启动一个
tshark子进程(Wireshark的命令行工具)负责底层数据包捕获,tshark会把捕获到的数据包以特定格式(比如XML)通过管道传给Pyshark的Python进程。 - 生成器的作用是逐个读取管道中的数据包数据,解析后返回给你的代码。当你的处理逻辑(比如
time.sleep(5))变慢时,tshark捕获的数据包会先存在管道缓冲区,缓冲区满了之后,tshark会把多余的数据包暂存到内存队列里——这就是你看到内存占用缓慢增长的原因。
简单来说:生成器本身不存储数据包,它只是负责“按需取数”,真正的积压数据是在tshark子进程的内存队列里,或者管道缓冲区中。
2. 处理速度跟不上时的后果
- 短期:内存占用持续增长,因为
tshark会不断把未被读取的数据包存在内存里。 - 长期:当内存占用超出系统可用内存时,操作系统会触发OOM(内存不足) Killer,直接终止
tshark或者Pyshark的Python进程;极端情况下会导致系统卡顿、无响应。 - 注:默认情况下
tshark不会主动丢弃数据包,直到内存耗尽或者进程被终止。
3. 关键注意事项
- 限制捕获范围:不要嗅探所有数据包,通过
tshark的过滤规则(比如capture = pyshark.LiveCapture(interface='Ethernet', display_filter='tcp port 80'))只捕获你需要的数据包,减少积压压力。 - 优化分析逻辑:重构混乱的分析代码,尽量减少单数据包处理时间;如果处理逻辑复杂,考虑用线程/进程池把捕获和分析解耦——比如一个线程负责读取数据包放到队列,另一个/多个线程负责分析入库。
- 设置缓冲区阈值:可以通过
tshark的命令行参数限制内存使用,比如添加-b filesize:1024(当捕获数据达到1024MB时自动切分文件),把部分数据转存到磁盘,避免内存耗尽。 - 监控内存占用:在生产环境中加入内存监控逻辑,当内存占用达到预警值时,触发告警或者临时停止捕获/清理积压数据。
内容的提问来源于stack exchange,提问作者Seth Thomas
相关产品推荐
相关产品推荐

