拓冰建站拓冰建站
首页 / 资讯中心 / 正文

用Python Flask搭建轻量级网络诊断面板,定位校园网卡顿

学校网太卡了这是很多住过宿舍、泡过实验室的人都踩过的坑。白天访问还正常晚高峰一到延迟飙高、丢包上升、网页转圈问题到底出在校园网出口带宽、DNS 解析、无线干扰还是本机网卡不测一下根本说不清楚。这次我们来看一个可以自己部署的轻量级网络诊断面板。它的思路很直接后端用 Python Flask 写测速和延迟检测接口前台套一个现成的 Web 管理模板跑起来之后通过浏览器查看当前网络状态、历史趋势和丢包情况。整个项目不需要 GPU不需要深度学习环境几十分钟就能跑通最小版本。问题定位清楚了再去找学校信息中心反馈或者调整实验室的网络策略就有数据支撑了。先给结论这个面板的特点是纯本地 Web 服务、Python 实现、无 GPU 需求、支持定时批量检测、提供 HTTP API、前端模板可替换。部署难度低适合网络排查、日常监控和接口集成的场景。下面我会按“环境准备 → 安装部署 → 功能测试 → 前端模板 → 接口与批量任务 → 资源占用 → 问题排查”的顺序展开末尾给出合规使用建议。1. 核心能力速览能力项说明项目类型本地网络诊断 Web 工具后端技术Python Flask可替换成 FastAPI前端模板Bootstrap 5 / AdminLTE 风格静态资源本地化主要功能延迟测试、带宽测速、DNS 解析耗时、丢包率、历史记录推荐硬件普通 PC、迷你主机、树莓派无 GPU 要求支持系统Windows / Linux / macOS需 Python 3.9启动方式命令行启动绑定自定义端口API 接口/api/health、/api/latency、/api/speed、/api/history批量任务使用 APScheduler 定时检测可选启用适用场景宿舍、实验室、办公室的校园网链路自查说明表格里的接口路径和功能清单是通用设计模板实际部署时建议按照自己的项目结构调整。不要把它当成某个现成仓库的完整文档重点是理解“后端接口 模板页面 定时任务”这套组合思路。2. 适用场景与使用边界这套面板解决的是“卡在哪”的问题不是“把网变快”的问题。它适合下面这些情况学生或开发者想收集网络质量数据向学校信息中心反馈时有依据。实验室或工作室需要监控办公网络的延迟和带宽波动。想验证不同时段、不同 DNS 服务器、不同网卡模式下的网络表现。想把网络质量数据接入到自己的监控系统或告警脚本里。不合适的场景也要说清楚不要用它去扫描校园网内未授权的主机和服务主动探测他人设备可能违反学校网络管理规定。不要用它绕过校园网认证、计费或访问控制机制。本文提到的所有功能只做本机或授权网关的常规测量。不要把它当作正式的网管平台。它能记录趋势、暴露问题但不会自动修复网络故障。合规提醒放在前面涉及网络测量时先确认你有权限对自己所在网段和目标主机发起 ICMP、DNS、HTTP 请求。涉及人脸、声音、设备指纹等信息采集的别碰。校园网属于公共基础设施任何未授权扫描都可能带来麻烦这一点务必重视。3. 环境准备与前置条件3.1 确认 Python 版本Flask 和 APScheduler 对 Python 版本要求不高但建议使用 3.9 以上。python --version如果系统里没有 Python先去官网安装或者在 Windows 的 Microsoft Store 里搜索 Python 3.11 或更高版本安装。Linux 下使用系统包管理器安装也可以。3.2 确认端口与静态资源目录默认会使用 8000 端口先检查端口是否被占用Windowsnetstat -ano | findstr :8000Linux / macOSlsof -i:8000如果端口被占用运行服务时换一个比如 8080 或 9000。模板页面需要的 Bootstrap、ECharts 等静态资源建议提前下载后放到static/目录。不要在页面上直接引用公网 CDN因为校园网访问外部 CDN 可能很慢甚至被拦截本地化资源才能保证面板在断网时也能打开。3.3 网络测量所需的权限延迟测试依赖 ICMP 协议部分校园网会限制 ICMP导致 ping 超时但网页能正常打开。遇到这种情况可以用 TCP 或 HTTP 探测代替 ping。速度测试依赖公网测速节点。如果校园网对测速域名有流量限制或 QoS 限制测出来的带宽不一定是你本机的真实带宽这一点在分析结果时要留意。4. 安装部署与启动方式4.1 创建项目结构推荐目录结构如下network-health-dashboard/ ├── app.py ├── requirements.txt ├── config.yaml ├── templates/ │ ├── base.html │ └── index.html ├── static/ │ ├── css/ │ │ ├── bootstrap.min.css │ │ └── custom.css │ ├── js/ │ │ ├── bootstrap.min.js │ │ ├── echarts.min.js │ │ └── main.js └── data/data/目录存放 SQLite 数据库历史记录会写到这里。templates/和static/是 Flask 默认的模板与静态资源目录名称不要随意改。4.2 安装依赖创建requirements.txt内容如下flask3.0.3 requests2.32.3 psutil5.9.8 ping34.0.8 speedtest-cli2.1.3 dnspython2.6.1 apscheduler3.10.4 pyyaml6.0.1版本号以后续实际安装结果为准如果某个包在你们学校的 pip 源里不可用去掉版本号重新安装pip install -r requirements.txt网络环境不稳定时可以换国内镜像源pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple4.3 后端开发app.py是一个最小可运行的 Flask 应用同时包含初始化数据库、页面路由、延迟测试接口和速度测试接口。import argparse import os import sqlite3 import time from datetime import datetime from flask import Flask, jsonify, render_template, request from ping3 import ping BASE_DIR os.path.dirname(os.path.abspath(__file__)) DATABASE os.path.join(BASE_DIR, data, history.db) app Flask(__name__) def get_db(): conn sqlite3.connect(DATABASE) conn.row_factory sqlite3.Row return conn def init_db(): os.makedirs(os.path.dirname(DATABASE), exist_okTrue) conn get_db() conn.execute( CREATE TABLE IF NOT EXISTS network_history ( id INTEGER PRIMARY KEY AUTOINCREMENT, test_type TEXT, target TEXT, value REAL, unit TEXT, created_at TEXT ) ) conn.commit() conn.close() def write_history(test_type, target, value, unit): conn get_db() conn.execute( INSERT INTO network_history (test_type, target, value, unit, created_at) VALUES (?, ?, ?, ?, ?), (test_type, target, value, unit, datetime.now().isoformat()), ) conn.commit() conn.close() app.route(/) def index(): return render_template(index.html) app.route(/api/health) def health(): return jsonify({status: ok, time: datetime.now().isoformat()}) app.route(/api/latency) def latency(): target request.args.get(target, 223.5.5.5) rtt ping(target, timeout3) if rtt is None: result {target: target, rtt_ms: None, reachable: False} write_history(latency, target, -1, ms) else: rtt_ms round(rtt * 1000, 2) result {target: target, rtt_ms: rtt_ms, reachable: True} write_history(latency, target, rtt_ms, ms) return jsonify(result) app.route(/api/history) def history(): test_type request.args.get(type, latency) limit request.args.get(limit, 50, typeint) conn get_db() rows conn.execute( SELECT * FROM network_history WHERE test_type ? ORDER BY id DESC LIMIT ?, (test_type, limit), ).fetchall() data [dict(row) for row in rows] return jsonify(data) if __name__ __main__: parser argparse.ArgumentParser() parser.add_argument(--host, default127.0.0.1) parser.add_argument(--port, typeint, default8000) args parser.parse_args() init_db() app.run(hostargs.host, portargs.port, debugFalse)代码里默认测试目标是223.5.5.5这是阿里公共 DNS。如果用校园网关做延迟测试把目标地址换成网关 IP。目标 IP 不要填对外部未授权服务器的地址。速度测试接口单独拆到一个路由里因为speedtest-cli的耗时比较长建议用异步执行或前端轮询结果。下面是简化的速度测试接口app.route(/api/speed) def speed(): import speedtest st speedtest.Speedtest() st.get_best_server() download st.download() / 1_000_000 upload st.upload() / 1_000_000 result { download_mbps: round(download, 2), upload_mbps: round(upload, 2), timestamp: datetime.now().isoformat(), } write_history(speed_download, speedtest.BEST_SERVER.get(host, unknown), download, Mbps) write_history(speed_upload, speedtest.BEST_SERVER.get(host, unknown), upload, Mbps) return jsonify(result)注意speedtest包的接口在不同版本中不完全一致生产环境里建议把测速逻辑封装成独立模块再在 API 层调用。4.4 启动服务在项目根目录执行python app.py --host 127.0.0.1 --port 8000启动后终端会显示 Flask 的访问地址。浏览器打开http://127.0.0.1:8000能看到模板页面说明服务正常。默认绑定127.0.0.1是为了安全只有本机能访问。如果需要在宿舍里用手机查看可以绑定到本机局域网 IPpython app.py --host 0.0.0.0 --port 8000绑定0.0.0.0后需要同步考虑防火墙和局域网访问控制。Windows 下开放端口需要管理员权限New-NetFirewallRule -DisplayName NetworkDashboard -Direction Inbound -Protocol TCP -LocalPort 8000 -Action AllowLinux 下可以使用 ufwsudo ufw allow 8000/tcp跨设备访问完成后建议改回127.0.0.1避免其他设备扫描到这个服务。5. 功能测试与效果验证5.1 服务健康检查先确认服务和数据库都正常。浏览器访问http://127.0.0.1:8000/api/health预期返回{ status: ok, time: 2025-01-01T12:00:00 }如果页面提示 404检查路由是否写错如果提示 500检查data/目录是否能写入。5.2 延迟测试访问下面链接默认测试目标为223.5.5.5http://127.0.0.1:8000/api/latency?target223.5.5.5预期返回{ target: 223.5.5.5, rtt_ms: 12.34, reachable: true }判断成功的标准很直接reachable为truertt_ms是正常数值。如果reachable为false说明 ICMP 探测被拦截或目标不可达。再增加一个对比测试把目标换成校园网网关 IP例如curl http://127.0.0.1:8000/api/latency?target192.168.1.1网关延迟明显低于公网 IP 是正常的。如果网关延迟也高问题可能出在无线链路或本机网卡。5.3 带宽测速调用速度测试接口curl http://127.0.0.1:8000/api/speed测速过程可能持续 30 到 60 秒接口超时时间要调大。返回结果包含上传和下载速率{ download_mbps: 85.23, upload_mbps: 20.11, timestamp: 2025-01-01T12:00:00 }宽带测速结果受测速节点影响很大同一个网络在不同节点下结果可能差很多。建议在同一个节点下跑三次取中位数不要用单次最高值作为结论。5.4 DNS 解析耗时测试新增一个/api/dns接口用dnspython测试域名解析耗时import dns.resolver app.route(/api/dns) def dns_check(): domain request.args.get(domain, www.baidu.com) dns_server request.args.get(dns, 223.5.5.5) resolver dns.resolver.Resolver() resolver.nameservers [dns_server] resolver.timeout 3 resolver.lifetime 3 start time.time() try: answers resolver.resolve(domain, A) cost_ms round((time.time() - start) * 1000, 2) result { domain: domain, dns_server: dns_server, resolve_time_ms: cost_ms, ip: answers[0].address, } except Exception: result { domain: domain, dns_server: dns_server, resolve_time_ms: None, ip: None, } return jsonify(result)测试时可以换成学校内部域名或常见公网域名。解析耗时超过几百毫秒说明 DNS 配置可能有问题可对比不同 DNS 服务器的耗时。5.5 历史记录验证跑完几次测试后打开http://127.0.0.1:8000/api/history?typelatencylimit10预期返回最近 10 条延迟记录。历史数据说明 SQLite 写入和查询链路是通的后面做定时批量任务时历史曲线就是从这里取数。6. Web 模板套用从静态页面到数据可视化“套个模板”不是简单下载一个 HTML 就完事关键是把后端返回的数据塞进模板并让静态资源能在本机稳定加载。先写templates/base.html统一页面布局!doctype html html langzh-CN head meta charsetutf-8 meta nameviewport contentwidthdevice-width, initial-scale1 title{% block title %}网络诊断面板{% endblock %}/title link relstylesheet href{{ url_for(static, filenamecss/bootstrap.min.css) }} link relstylesheet href{{ url_for(static, filenamecss/custom.css) }} /head body div classcontainer-fluid div classrow nav classcol-md-2 sidebar h5网络诊断面板/h5 ul lia href/首页/a/li lia href/history历史记录/a/li /ul /nav main classcol-md-10 {% block content %}{% endblock %} /main /div /div script src{{ url_for(static, filenamejs/echarts.min.js) }}/script {% block scripts %}{% endblock %} /body /html再写templates/index.html{% extends base.html %} {% block content %} div classcard h5延迟测试/h5 div classform-group input typetext idtarget value223.5.5.5 classform-control /div button classbtn btn-primary idrun-latency运行延迟测试/button div idlatency-result classmt-3/div /div div classcard h5延迟趋势/h5 div idchart styleheight: 300px;/div /div {% endblock %} {% block scripts %} script document.getElementById(run-latency).addEventListener(click, async () { const target document.getElementById(target).value; const resp await fetch(/api/latency?target encodeURIComponent(target)); const data await resp.json(); document.getElementById(latency-result).textContent 延迟: data.rtt_ms ms, 可达: data.reachable; loadHistory(); }); async function loadHistory() { const resp await fetch(/api/history?typelatencylimit30); const rows await resp.json(); const times rows.map(function(row) { return row.created_at; }); const values rows.map(function(row) { return row.value; }); const chart echarts.init(document.getElementById(chart)); chart.setOption({ xAxis: { type: category, data: times }, yAxis: { type: value }, series: [{ type: line, data: values, smooth: true }] }); } loadHistory(); /script {% endblock %}模板套用有几个容易踩的坑静态资源路径必须用url_for(static, filename...)生成不能写死/static/css/bootstrap.min.css不然子路由下会 404。CDN 资源在校园网内不一定快把 Bootstrap 和 ECharts 的文件下载到本地。图表数据为空时ECharts 会显示空白区域要判断一下历史记录接口是否返回了数据。如果需要更专业的管理后台风格可以直接套 AdminLTE 或 Tabler 这类开源模板把模板的dist静态文件放到static/下再改一下base.html的导航结构即可。模板只是皮核心还是接口返回的数据结构。7. 接口 API 与批量任务7.1 API 一览接口方法参数说明/api/healthGET无服务健康检查/api/latencyGETtarget延迟测试/api/speedGET无带宽测速/api/dnsGETdomain、dnsDNS 解析耗时/api/historyGETtype、limit查询历史记录接口设计可以让你把网络质量数据接到自己的脚本或告警系统里这也是最有复用价值的部分。7.2 curl 调用curl http://127.0.0.1:8000/api/latency?target1.2.4.81.2.4.8是 CNNIC 公共 DNS可以在国内网络环境下使用。7.3 Python 调用写一个小脚本批量测试多个目标import time import requests API_BASE http://127.0.0.1:8000 TARGETS [ 223.5.5.5, 1.2.4.8, 你的校园网网关IP, ] def batch_latency(): for target in TARGETS: try: resp requests.get( f{API_BASE}/api/latency, params{target: target}, timeout10, ) print(target, resp.json()) except requests.RequestException as exc: print(target, 请求失败, exc) time.sleep(1) if __name__ __main__: batch_latency()批量测试时要控制并发和频率避免给自己的网卡造成额外负载。7.4 定时批量任务定时任务可以使用 APScheduler在app.py里启动后台调度器from apscheduler.schedulers.background import BackgroundScheduler def periodic_check(): rtt ping(223.5.5.5, timeout3) if rtt is not None: write_history(latency, 223.5.5.5, round(rtt * 1000, 2), ms) scheduler BackgroundScheduler() scheduler.add_job(periodic_check, interval, minutes30) scheduler.start()这样每 30 分钟记录一次延迟。保存后重启服务持续跑一两天就能从历史数据看到晚高峰延迟飙升的具体时间点。8. 资源占用与性能观察这个面板没有 GPU 推理资源占用主要来自 Python 解释器、Flask 服务和 SQLite 写入。用户排查时重点观察三个维度CPU 占用低负载运行时 CPU 占用很低测速或批量任务执行时会有短时上升。观察方法Windows 用任务管理器Linux 用top或htop。内存占用具体占用取决于依赖项数量通常不会太高。确认方式是在任务管理器里观察python进程的内存列。磁盘占用SQLite 数据库会随时间增长每条历史记录包含时间戳、测试类型、目标、值等字段运行几个月也只是百 MB 级别不需要频繁清理。测速接口是阻塞式的如果同时有多个请求进来后发的请求会被前面的测速阻塞。建议在测速接口前加一个单飞控制避免并发测速把网络带宽打满。简单做法import threading speed_test_lock threading.Lock() app.route(/api/speed) def speed(): if not speed_test_lock.acquire(blockingFalse): return jsonify({error: speed test already running}), 429 try: # 测速逻辑 pass finally: speed_test_lock.release()端口冲突也是常见问题。如果服务启动时报Address already in use先找到占用进程再杀掉或者直接换端口启动。9. 常见问题与排查方法问题现象可能原因排查方式解决方案pip install 失败网络不稳定或 Python 版本过低查看报错信息换国内镜像源升级 Python启动后页面打不开端口被占用或服务未启动查看终端日志换端口重新启动页面有文字没有样式静态资源路径错误浏览器 F12 看 Network 请求使用 url_for 生成静态路径延迟测试一直超时ICMP 被防火墙拦截用其他主机 ping 目标放行 ICMP 或改用 http 探测测速接口卡死网络节点不可达看测速日志换测速节点增加超时SQLite 写入报错data 目录不存在检查目录创建 data 目录局域网内手机无法访问绑定地址不是 0.0.0.0检查启动参数切换到 0.0.0.0配置防火墙历史记录为空还没触发时序接口查看数据库表先手动访问一次接口依赖安装失败时不要盲目升级所有包把报错信息里的包名单独安装通常是因为某个包版本和当前 Python 版本不兼容。10. 最佳实践与使用建议第一次部署时先拿最小配置跑通流程不要一上来就放四个测试指标。建议先做延迟测试加一个目标跑通后再扩展带宽、DNS 和定时任务。数据管理上输入素材、测试配置、SQLite 数据库分目录存放config.yaml中统一管理测试目标、测速节点和定时任务间隔。这样后续调整参数时不需要改代码。接口服务如果对局域网开放要限制访问范围。最简单的方式是只绑定127.0.0.1或者用防火墙放行指定 IP 段。不要把面板直接部署到公网服务器上测速接口会被别人当成免费探针使用。批量任务和定时检测要加日志。APScheduler 的周期任务如果出现异常需要在回调里捕获def periodic_check(): try: rtt ping(223.5.5.5, timeout3) if rtt is not None: write_history(latency, 223.5.5.5, round(rtt * 1000, 2), ms) except Exception: pass最后强调一下合规边界。排查校园网卡顿重点是收集同一时段的多项指标判断瓶颈在出口带宽、DNS 还是无线链路。让面板持续记录 24 到 48 小时再对比高峰和非高峰的曲线比临时测一两次更有价值。如果你们学校对校园网设备有明确的测试要求先确认授权范围未授权的主动探测不要做。这个面板只做被动测量和常规测速不碰认证、计费和设备管理功能这样用起来最安全。先让最小版本跑起来把延迟历史记录下来再决定要不要加更多功能。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门