这一年,我用 Rust 做了管理后台、服务器监控、埋点分析、自动报表和视频转码,也做了磁盘清理、剪贴板和压缩工具。

这些东西看起来分散,我面对的其实一直是同一个问题:怎样把依赖脚本、人工操作或者临时页面的工作,变成可以部署、可以维护,出了问题也能够继续定位的系统。

刚开始我更在意能不能把第一版做出来。等这些系统真正运行起来,我才发现,后面出现的内存、存储、时间窗口和部署问题,更考验一个系统是否可靠,也逐渐改变了我的判断方式。

我用 Rust 做了哪些系统

最早持续演进的是 rustzen-admin。它从用户、角色、菜单、字典和操作日志这些后台功能开始,后来加入仪表盘、权限同步、任务管理、部署版本管理和完整的发布目录,存储也从依赖 PostgreSQL 转向 SQLite-first。它解决的不是“再做一个管理后台”,而是以后启动一个 Rust 全栈项目时,不必重新处理认证、权限、配置、存储和部署这些基础问题。

服务器侧,我做了监控、埋点分析和自动报表系统,其中监控和埋点相关能力部署在约一百台服务器上。监控系统由中心服务、节点 Agent 和管理端组成,负责采集指标、管理节点、配置告警、执行部署和生成周期报表。埋点系统负责接收页面、接口和用户事件,再完成聚合、查询和报表生成。自动报表系统则把定时任务、数据处理、模板执行和结果上传串在一起。

视频场景里,我用 Rust、Axum、GStreamer 和 FFmpeg 做过 RTSP 到 WebRTC、FLV 的转码服务,也处理了离线安装、运行能力检测和连接限制。它让我接触到的不再只是普通 HTTP 接口,还有媒体管线、子进程、连接生命周期和系统依赖。

桌面端和命令行方向,我做了开发环境磁盘分析与清理、剪贴板历史以及发布压缩工具。它们解决的问题更靠近个人电脑:识别开发缓存属于哪个工具和项目,在删除前判断能不能恢复;本地保存和检索剪贴板历史;在 npm 和发布脚本中调用跨平台 Rust 二进制完成归档。

这些项目让我接触了 Axum、Tokio、SQLx、SQLite、Tauri、文件系统、系统进程和媒体处理。但真正留下来的经验,不是又记住了多少 API,而是系统运行以后怎样给资源和状态补上边界。

一百台服务器会把小问题变成长期问题

开发环境里,一个采集任务多占一点内存,一张表多存一些数据,往往不容易察觉。部署到约一百台服务器以后,这些问题会持续出现。

有些节点的内存会阶段性过高。最开始看到的是一个数值,但数值本身不能说明根因。它可能是短时峰值、持续增长,也可能和采集任务的并发、缓存或缓冲区有关。仓库中已经做过部分指标内存优化和边界控制,但阶段性高内存的根因仍未确认。后续还需要保留能够区分短时峰值与持续增长的观测,再决定是否进一步限制遍历、并发、缓存或缓冲区。

存储问题更直接。原始指标、埋点事件、聚合结果、告警记录和日志如果都只管写入,不定义保留周期,磁盘迟早会被占满。我后来把处理拆成几层,相关实现已经进入仓库,但仍未完成全部验证:原始数据和聚合数据使用不同的保留周期;清理任务分批删除,避免一次事务锁住太多数据;对 SQLite 调整写入和维护参数;在写入链路中使用批量接收、异步聚合,并减少聚合任务之间的写竞争。

还有一些问题不是“数据太多”,而是“数据算错了”。例如 P95 不能从已经汇总过的平均值再次推算;日报、周报和补跑任务必须统一时区和时间窗口;节点失联以后,旧告警不能一直保持激活状态。这些问题最后都要求我回到原始分布、明确业务时间,并给告警状态增加恢复与清理流程。

节点磁盘、挂载点和 Docker 存储的识别目前还没有完全解决。宿主机磁盘、挂载关系、Docker volume 和容器存储层并不是互不相关的几类数据。下一步需要先把它们的关系和归属识别清楚,再讨论容量统计、告警和清理,不能只把几个数值放到同一张图上。

部署以后,环境也是系统的一部分

另一个反复出现的问题是:本地能运行,并不等于能稳定部署。

服务器架构可能不同,Agent 包需要按远端架构选择;重复安装需要保留数据库、配置、日志和已上传版本;部署失败要处理临时文件和回滚;周期任务需要在运行时启动前确定时区;视频服务还要面对 GStreamer 插件、FFmpeg、离线依赖和运行能力检测。

我以前更容易把这些看成安装脚本的问题。后来发现,运行目录、配置来源、文件保留、服务用户、回滚路径和依赖检测本来就是产品契约的一部分。如果它们没有被写进系统边界,代码本身再整齐,部署仍然会不断产生例外。

桌面端也是一样。磁盘扫描不能无限遍历,工作线程不能无限增加,还要跳过没有权限的目录、应用数据和不应该触碰的媒体库。清理动作需要保留恢复信息,避免一次误判直接变成不可逆删除。剪贴板恢复以后,还要避免把刚恢复的内容再次采集成一条新记录。

这些都不是功能列表上的大功能,却决定了一个工具能不能放心使用。

AI 改变了我工作的重心

这一年里,AI 参与了很多具体实施:读取仓库、补代码、调整目录、对齐前后端类型、运行测试和构建,再根据结果继续修改。它让我能够把媒体服务、桌面端、部署和全栈工程中的更多实施任务拆开推进,也拓展了我能处理的问题边界。

但实现速度提高以后,我花更多时间思考的反而是做什么、为什么做、怎样拆,以及什么证据足以说明完成。

例如“优化内存”不是让 AI 随便减少几个缓存,而是先说明目前只观察到了阶段性高内存,哪些根因还没有证据,准备采集什么信息,资源上限放在哪里,修改后怎样比较。让 AI 执行验证也不等于结果已经可靠:构建通过只证明能够构建,有限测试只覆盖已写出的情况,线上资源问题还需要新的观测周期。

这也带来了新的挑战。我需要更准确地描述事实和计划,不能把准备做的事情写成已经完成;需要把大任务拆成能够独立验收的步骤;还要在 AI 给出一批看起来合理的改动时,判断它是否越过了系统边界。

这一年真正增长的是什么

以前我更容易用功能判断进度:接口写完了,页面出来了,服务部署了。现在我会继续追问:内存有没有上限,数据保留多久,时间窗口是否一致,失败以后怎样恢复,重复部署会不会破坏已有状态,验证结果究竟证明了什么。

Rust 当然让我更熟悉类型、并发、错误处理和资源生命周期。但这一年更重要的成长,是我开始从“把功能实现出来”转向“让系统的边界可以被说明和验证”。

后续我会先继续完善内存限制、存储策略以及节点磁盘与 Docker 存储识别。等这些方案在真实场景中验证以后,再把适合复用的部分更新到 rustzen-admin。计划暂时只有这一条,不再同时铺开更多改造。

具体实施可以更多交给 AI,最终要做什么、怎样做,以及什么结果值得接受,仍然是我需要承担的工作。