Spot Monitor

参考

性能

测试机是 3 核 3.8 GiB 的 Xeon E5-2699 v4,Debian 12,release 构建(LTO + opt-level=z + strip)。负载来自一个模拟 agent 程序。

这一页的数字实测于上游 hub v1.2.0、agent v1.1.0 的发布版二进制(musl 静态链接,与 Docker 镜像里的是同一个),用来说明这套设计的大致量级。本站对应的当前版本没有按同一套方法逐项复测,绝对值请以你自己的机器为准。

装机体积

hub 可执行文件6.3 MiB
agent 可执行文件1.8 MiB
hub 冷启动到能响应请求(8 个节点、7 天历史的库)70 ms
30 天历史数据(7 个节点)15.7 MiB

一个二进制加一个 .db 文件就是全部,没有配置文件,也没有额外目录。

内存

场景RSS
hub 空转6.5 MiB
hub,200 个节点在线,每 2 秒上报一次8.4 MiB
hub,每秒 1000 次上报8.6 MiB
hub,每秒 1000 次上报 + 8 个人同时刷状态页18.2 MiB
agent,线上实例常驻2.0 MiB

每秒 1000 次上报大约等于 1000 个节点按默认的 1 秒间隔在报。负载上去基本不涨,Rust 没有 GC,也没有语言运行时。

密码登录

上面量的是 agent 负载,不含面板的密码登录。密码校验走 argon2,一次要 19 MiB,用完即还给系统,常驻内存不会因为有人登录过而上涨:

RSS
登录前6.5 MiB
串行密码登录 20 次,过程中的峰值25.4 MiB
登录完6.6 MiB

并发登录由闸门挡住:同一时刻只算一次 argon2,其余请求直接返回 429,不排队。8 个请求同时登录,峰值同样是 25.6 MiB。首次启动生成应急密码也要算一次,所以刚装好的 hub 峰值就已经在 25 MiB 左右。

自己用 glibc 目标构建(cargo build --release 的默认目标)不一样:glibc 不把这块内存还给系统,每次密码登录常驻内存涨一截,串行登录 50 次后停在约 350 MiB,超过单元文件给的 MemoryMax=256M。自己构建请用 musl 目标;发布的二进制和 Docker 镜像都是 musl,没有这个问题。

CPU

干同样的活烧掉多少 CPU 秒:

场景
200 节点每 2 秒上报,跑 90 秒2.3 秒
每秒 1000 次上报,跑 60 秒16.1 秒
上报 + 刷状态页混合,跑 90 秒33.0 秒

换算一下,200 个节点在线时占一颗核的 2.5%。

状态页响应速度

在每秒 1000 次上报的同时,8 个并发不停地刷状态页:

每秒处理的请求数723
中位延迟9.4 ms
p99 延迟33 ms

723 这个数打到了压测客户端自己的上限,真实上限更高。

这些数字是调出来的

光换语言只拿得到体积和内存的优势。同样的混合负载,调优前后:

调优前调优后
内存43.3 MiB18.2 MiB降 58%
CPU(90 秒)99.3 秒33.0 秒降 67%
状态页每秒请求数26723高 28 倍
p99 延迟842 ms33 ms快 26 倍

改动只有四处,都很小:

  1. WebSocket 读缓冲从 128 KiB 降到 4 KiB。库的默认值是按大文件传输定的,一个上报包只有几百字节,200 个连接就是 25 MiB 白占的内存
  2. 节点列表不再逐个查流量。原来渲染 200 个节点要查 200 次数据库,现在一次查完
  3. 状态页的 HTTP 接口复用已有的 2 秒快照缓存。这个缓存本来就在,但只有 WebSocket 那条路走它
  4. 调了三个 SQLite 参数:8 MiB page cache、WAL 检查点阈值和大小上限
在 GitHub 上修改这一页最后更新 2026-10-02