飞牛NAS必装:进程级资源监控,比自带强10倍
前言:飞牛自带的监控,为什么不够用#
飞牛 NAS 自带的资源监控只有一个百分比数字:CPU 多少、内存多少,没了。但实际运维中真正要回答的问题是:是哪个进程在吃 CPU?内存被谁占了?CPU 烧到多少度?风扇转不转?这台机器的配置到底顶不顶得住?哪块盘快坏了?哪个端口被谁占着?
于是我写了 fnos-resmon(飞牛资源管理器):一个单文件 Flask + psutil 的轻量监控面板,专为飞牛 NAS 设计,一条 docker 命令启动,浏览器打开 http://NAS-IP:7031 就能看,手机也能看。
开源地址:https://gitea.88531.cn/jinghui/fnos-resmon
一、它能做什么#
- CPU 面板:型号 / 架构 / 物理核 / 逻辑核 / 每核频率占用,进程级 CPU 排行(进程名 / PID / 用户 / 状态 / 线程数),点表头即排序
- 🌡️ 温度 / 🌀 风扇面板:11 路温度 + 风扇实时 RPM,超温变色预警,读不到的机器显示友好提示不报错
- 📊 负载诊断:1 分钟负载 ÷ 逻辑核数 = 单核负载,直接告诉你"顶得住还是顶不住",并点名头号吃 CPU 进程
- 🚀 一键优化系统:数据落盘 + 回收内存缓存 + 内存碎片整理,实测一次释放 500MB+
- 内存面板:每个进程 RSS / USS / SWAP 三列细分,物理内存槽位(容量 / 类型 / 频率 / 厂商)全展示,🧹 绿色大按钮一键回收内存
- 磁盘面板:SMART 健康 / 温度 / 通电时间 / 坏道重映射,阵列拓扑、挂载点用量、进程 IO 排行
- 网络面板:实时上下行速率、累计收发、连接数,所有 TCP 连接和侦听端口明细(进程 + 地址 + 状态),网卡驱动 / 速率 / 双工 / MTU
- 一键 kill 异常进程,右上角可调刷新间隔(3s / 5s / 10s / 30s / 60s)+ ⏸ 随时暂停
二、实现原理:容器里怎么读到宿主真实数据#
监控跑在 Docker 里,默认只能看到容器自己的 namespace。要读宿主真实数据,靠三招:
services:
fnos-resmon:
image: jpccr.ccs.tencentyun.com/jinghui/fnos-resmon:latest
network_mode: host
pid: host # 与宿主共享 PID 命名空间
privileged: true
volumes:
- /proc:/host/proc:rw # 宿主 proc
- /sys:/host/sys:ro # 宿主 sysfs(温度/风扇/网卡从这读)
1. CPU / 内存 / 进程:psutil 重定向 PROCFS。启动时把 psutil.PROCFS_PATH 指向 /host/proc,之后所有 psutil.process_iter / cpu_percent / virtual_memory 读到的都是宿主数据:
PROCFS = os.environ.get("PROCFS_PATH", "/host/proc")
if os.path.isdir(PROCFS):
psutil.PROCFS_PATH = PROCFS
2. 网络:nsenter 进宿主 netns。容器即使 bridged 模式,直读 /proc/net 也只能看到容器自身。网络类数据统一经 nsenter --target 1 --mount --net 在宿主(PID 1)netns 里执行 cat /proc/net/dev 和 ss -tunHn state all,失败才回退到 psutil 容器视角:
NSENTER = ["nsenter", "--target", "1", "--mount", "--net"]
def _host_ss():
"""宿主 tcp/udp 连接+监听,经 nsenter 在宿主 netns 执行 ss"""
out = _nsenter_run(["ss", "-tunHn", "state", "all"])
ss 行尾的 ("进程名",pid=1234,...) 会被正则抠出来,再用进程表按 PID 补齐进程名,前 80 条连接 + 前 80 条监听返回前端。
3. 后台采样线程 + 2 秒缓存。进程 CPU 统计需要两次采样算差值,所以 sample_procs() 先全员 cpu_percent(None) 打点,sleep 1 秒后再读数,按 CPU 倒序,前端每 2 秒拿到的是缓存,不会每次请求都卡 1 秒:
def sampler_loop():
while True:
try:
sample_procs()
except Exception:
pass
time.sleep(2)
threading.Thread(target=sampler_loop, daemon=True).start()
每个进程采集的字段:cpu / mem / rss / uss / swap / 线程数 / 用户 / 状态 / IO 读写 / 连接数。容器内 /etc/passwd 没有宿主用户,纯数字 uid 会经 /host/etc/passwd 还原用户名(5 分钟缓存)。
三、两个最实用的接口:负载诊断与一键优化#
GET /api/cpu/advise —— 配置顶不顶得住,一句话结论。公式很简单:单核负载 = 1分钟load ÷ 逻辑核数,分四档给结论,并点名最吃 CPU 的进程、给出扩容 / 杀进程 / 属正常的建议:
@app.route("/api/cpu/advise")
def api_cpu_advise():
load = list(os.getloadavg()) # 1/5/15 分钟
per_core = load[0] / logical # 单核负载
# 四档:<0.7 轻松 / <1.0 饱和 / <2.0 吃力 / 更高 过载
POST /api/sys/optimize —— 一键优化。依次做三件事:sync 数据落盘 → 写 /host/proc/sys/vm/drop_caches 回收 pagecache → 写 /host/proc/sys/vm/compact_memory 整理碎片。内存面板另有 POST /api/mem/drop 单独回收。零侵入:只调内核已有接口,不改系统文件。
GET /api/sensors —— 温度风扇。优先读 /host/sys/class/hwmon,回退 /sys/class/hwmon,temp*_input ÷ 1000 得摄氏度,fan*_input 即 RPM,label 优先用 temp*_label。超温阈值前端变色预警,风扇节点不存在(如纯 NAS 小主机无风扇上报)的机器返回空 + 友好提示,不阻塞主流程。
四、API 一览#
| 方法 | 路径 | 作用 |
|---|---|---|
| GET | /api/cpu |
CPU 信息 + 每核占用 + 进程排行 + load |
| GET | /api/mem |
内存占用 + RSS/USS/SWAP 进程明细 + 槽位硬件 |
| GET | /api/disk |
挂载用量 + SMART/温度/通电时间 + 阵列 + IO 排行 |
| GET | /api/net |
网卡速率 + TCP/监听明细 + 硬件(驱动/MTU/双工) |
| GET | /api/sensors |
11 路温度 + 风扇 RPM |
| GET | /api/cpu/advise |
负载诊断:四档结论 + 头号进程 + 建议 |
| POST | /api/sys/optimize |
一键优化:落盘 + 回收缓存 + 内存整理 |
| POST | /api/mem/drop |
一键内存回收 |
| POST | /api/kill |
结束异常进程(限宿主 PID) |
| GET | /api/health |
健康检查 |
五、部署:一条命令#
docker run -d --name fnos-resmon -p 7031:7031 --privileged \
-v /proc:/host/proc:rw -v /sys:/host/sys:ro \
jpccr.ccs.tencentyun.com/jinghui/fnos-resmon:latest
浏览器打开 http://NAS-IP:7031 即可。前端是单个静态页(改前端必须重建镜像),后端一个 app.py 约 1100 行,无数据库,开箱即用。
六、实测截图(v1.3.4 当前版本)#
CPU 面板:63°C 红色预警、风扇 1200 转 RPM、负载诊断四档结论、一键优化按钮:

内存面板:RSS/USS/SWAP 三列细分 + 🧹 一键回收大按钮:

磁盘面板:3 盘 SMART 全 PASSED + 温度通电时间:

网络面板:qbittorrent 482 连接一眼揪出吃带宽进程:

七、总结#
飞牛自带监控解决"有没有",fnos-resmon 解决"是谁、多少度、顶不顶得住、能不能一键收拾"。核心就三招:psutil 重定向宿主 proc、nsenter 进宿主 netns 读网络、后台线程 2 秒缓存进程快照,剩下的都是把数据摆整齐。如果你也在飞牛上跑了很多 Docker 服务,装一个看看头号吃 CPU 的到底是谁 —— 八成有惊喜。
镜像:jpccr.ccs.tencentyun.com/jinghui/fnos-resmon:latest | 开源:https://gitea.88531.cn/jinghui/fnos-resmon | 端口 7031,欢迎提 issue。