Files
MoShiro/docs/roadmap.md
T
2026-10-04 21:46:39 +08:00

11 KiB
Raw Blame History

里程碑

每个里程碑都以“可运行、可验证”作为完成标准;可执行程序在各自的目标 RID 上(见 project-layout.md 第 9 节,Probe 包括 linux-musl-x64 和 linux-musl-arm64)的 NativeAOT 发布必须通过,并且零 AOT/trim 警告。

M0 骨架

  • 按 project-layout.md 建立仓库:backend/ 下的 props、.editorconfig、BannedSymbols.txt 与 BannedSymbols.Node.txt、backend/fleet/ 骨架、三个 .slnx、两个 Monitor 共享库、Backend 的六个项目。
  • CI:Windows/Linux 矩阵、路径过滤、dotnet format --verify-no-changes、scripts/check-deps、scripts/check-openapi、AOT 发布,并记录体积和内存基线。

验收:

  • 三个空程序以 AOT 方式发布并启动;
  • 在 Agent 中调用 Process.Start 时构建失败;
  • 空的 Probe 能在 OpenWrt aarch64 真机或 QEMU 上启动,并完成一次 TLS 握手(验证 musl 与 libopenssl3);
  • 给出 linux-musl-arm(armv7)工具链的验证结论。

F1 Fleet 核心(与 M1 并行)

  • Fleet.Core、Fleet.Identity、Fleet.Rpc、Fleet.Link(连接服务端、点对点会话、发件箱、期望状态同步)、Fleet.Hosting、Fleet.Enrollment.Client、fleet-enroll、Fleet.Server.Enrollment、Fleet.Server.Link、Fleet.Server.Sqlite。
  • samples/EchoNode 与 EchoServer:用不依赖 Monitor 的方式跑通注册 → 认证 → 状态同步 → 发件箱上报 → 断线重连。

验收:

  • scripts/check-deps 证明 backend/fleet/** 不引用 Monitor.*;
  • EchoNode 在 Backend 重启、网络中断 10 分钟后能恢复,上报的消息不重复也不丢失(队列未满时);
  • 伪造签名、重放 nonce、调用本地未允许的方法,全部被拒绝。

M1 声明与积木(本机回环)

  • Protocol:ParamSpec、KindSpec、自描述 RawChunk 编解码(附黄金字节测试)、JSON-RPC 信封。
  • Measurement:Transport(udp/tcp/tls)、Pacer(fixed/ladder)、Payload、Behavior(echo/sink/source/connect/hold)、Sampler(tcp_info),以及 Recorder、KindAssembler、BudgetGuard。
  • tools/monitor-bench:用两个本地进程运行任意 Kind,导出 RawChunk,用来调试引擎。
  • 测试:通过丢包注入中继验证逐包记录的完整性;100 Mbps 下发送节奏误差 < 1%;只加一条 Kind 声明、不写代码,就能运行一种新的组合。

M2 Probe ↔ 多个 Agent

  • Probe 与 Agent 之间的签名认证、会话、MAC、重放窗口、限速、源地址漫游;TaskReconciler;列的交付与合并;每 10 秒切块。
  • Probe 同时与多个 Agent 维持会话(先用静态列表)。
  • 开发模式:Agent 把 RawChunk 写入本地目录(正式运行时不落盘)。

验收:一个家宽 Probe 同时连接 3 台以上 VPS,连续运行 24 小时;原始块完整,内存稳定;宽带重拨后能自动恢复。

M3 Backend:注册、RPC、存储

  • 在 Fleet 之上接入:IFleetStore 实现、TaskSet 状态提供者(有效任务集的计算与下发)、RawChunk 收件箱、monitor.* 方法、monitor.probe.agents 同步。
  • 段文件与索引、发件箱 ACK、去重、缺口;管理员账号、Cookie 会话、API 令牌;/api/admin 中的节点、令牌、Probe 身份、任务管理。

验收:用一行安装命令部署一台新 VPS,自动注册 → 自动生成线路任务 → Probe 自动连接 → 1 分钟内在 /api/admin 中看到它的原始块。整个过程不需要手工配置。

M4 分析层与实时

  • 累加器、算子、首批 MetricDef、base/mc/hy2/reality 模型 v1;流式路径与持久路径;降采样;指标指纹与回填。
  • 查询(query.md):RangeResolver、SourcePlanner、1s 热层(1 小时)、metric_10s、现场合并、精确汇总;/overview?range=、/series、/compare、/distribution、/heatmap、/catalog/*(包括 presets);SSE 的 series 和 overview 主题;按需测试与测试结果。
  • 查询验收:近 5 分钟 1s 步长和近 15 分钟 2s 步长的响应时间 < 50 ms;7 天 15 分钟步长的响应时间 < 200 ms;同一时间段内,汇总值与“从原始块直接计算”的结果一致(直方图分位数误差 ≤ 4.5%)。

验收:

  • 扩展性:新增一个指标只需一行 MetricDef,重启后通过 API 可以看到它,并且 30 天历史已经回填;
  • 校准:在两条线路上实际部署 Hysteria2 和 REALITY 服务并实测,与推算结果对比,把偏差记录进 docs/calibration.md。

M5 规模与保留

  • 用模拟数据验证 15 个 Agent 运行 30 天的情况:存储量、查询延迟(30 天跨度 < 500 ms)、回填耗时、SSE 在 100 个连接下的表现。
  • 保留清理、磁盘占用指标、目标任务(icmp_echo、connect)与 allowed_target_cidrs。

F2 Fleet 更新(在 M6 之前)

  • Fleet.Update、fleet-updater(systemd 与 Windows 服务适配器、健康信标、回滚、防回滚)、fleet-release(CI 签名)、Fleet.Server.Releases(通道、灰度、版本汇总)。

验收:

  • 用 EchoNode 和 monitor-agent 两个应用验证“同一个 updater 管理多个产品”;
  • 验签失败、sha256 不符、新版本健康检查超时,这三种情况都能正确拒绝或回滚;
  • 面板被替换为恶意面板时,节点不会安装未签名的版本。

M6 加固与部署

  • OpenWrt 打包:procd 脚本、ipk/apk 包、sysupgrade 保留列表、libopenssl3 依赖检查;在 aarch64 路由器上跑满 24 小时,并运行一次 hy2_ladder(观察 CPU 饱和标记)。
  • 安装脚本的下载和验签(现在的 install.sh 从解压好的发布目录安装)、install.ps1 和 Windows 服务、fleet-updater 的配置。
  • 安全:对 UDP 包、控制帧、RawChunk、JSON-RPC 做模糊测试;伪造签名和重放测试;检查登录限流和 CSRF。

以后

  • 告警(Webhook);真实 QUIC 握手积木(依赖 msquic,需要单独评估);pcap/eBPF 采集。

实现状态(后端与 Agent)

已实现并有自动化测试(287 个,另有 2 个跳过的测试,其中 1 个需要运行中 NativeAOT 产物):

  • 多 Probe:Probe 身份由 Backend 生成(创建、轮换密钥、吊销、删除),一条线路是一对(Probe,Agent),Agent 为每个 Probe 会话各起一组流,数据按 line:<probe_id> 隔离;Agent 上报连着的 Probe(id、版本、远端地址、时间),管理端可以断开某个 Probe;吊销立即生效。

  • tcp_bulk 原语:批量传输(fwd / rev、本地码率上限、两端的 tcp_info),评分用持续 1 秒的吞吐峰值。

  • Agent 主机状态:只上报汇总数字(没有型号和 IP),实时推给展示页,每分钟存一个样本。

  • 前端:web/display(Agent 卡片总览、线路详情、按 Probe 的线路对比,拖动放大、只提供有数据的时间范围)和 web/admin(Agent、Probe、任务、按需测试、系统),共享「纸墨」主题;页面里可以把数据源指到别的后端(API 令牌 + 可选的 CORS 白名单 Monitor__CorsOrigins)。

  • 真实线路试跑:广东移动家宽 → 日本 IIJ 的 VPS(见 deployment.md)。

  • F1 的服务端部分:Fleet.Core/Identity/Rpc、Fleet.Server.Abstractions/Enrollment/Link(注册、签名认证、期望状态同步、发件箱收件箱、服务端发起的调用)。

  • M3:注册、RPC、段文件与 SQLite、任务集下发、管理 API。

  • M4(除校准外):累加器、算子、指标注册制、四个模型、流式与持久两条路径、降采样、指标指纹与回填、查询层(范围、步长、数据分层、精确汇总、列式响应)、SSE、按需测试。

  • M5 的一部分:保留清理。

  • F1 的节点部分:Fleet.Link(链路、发件箱、点对点监听与连接)、Fleet.Hosting、Fleet.Enrollment.Client 与 fleet-enroll。

  • Agent(M1 的一部分):Monitor.Agent(NativeAOT 可发布)与 Monitor.Measurement(列块合并、预算守卫)。UDP/TCP 数据面(认证、重放窗口、限速、端点学习)、线路任务调和、目标任务(icmp_echo、connect)、按需测试编排(udp_train 由 Agent 发包)。测试里的假 Probe(ProbeSimulator)通过真实的点对点握手连接真实的 Agent 与后端,端到端覆盖。详见 backend/agent/README.md。

  • Probe(M0/M2 的一部分):Monitor.Probe(NativeAOT,5.6 MB,常驻约 22 MB)——Agent 列表(bootstrap → 由 Agent 代为查询 → 推送,写回 agents.json)、每个 Agent 一个自动重连的会话、udp_echo/tcp_echo/connect/hold 角色、udp_train 接收端(按序号范围切块)、时钟偏移估计、有界发件箱。真实 Probe + 真实 Agent + 真实后端的端到端测试,以及用发布的 AOT 二进制做过的冒烟(内存稳定、CPU < 1%)。详见 backend/probe/README.md。

  • 采集积木统一(重构):Probe 和 Agent 的数据面合并成 Monitor.Measurement 里的一份实现(每种采集方法一个文件、拨号方和监听方一对角色,UdpMux/Tcp/RowStore 共用);合并改成由 Kind 的流声明(Driver、Key)驱动;测试方案移回 Backend;架构测试禁止采集层出现业务概念。

  • TCP 内核采样与长尾:tcp_echo 两端各自采样套接字的 TCP_INFO(Linux,union 流拼接);tcp.rtt 增加 p999、max、长尾比 tail,新增 tcp.slow(块内基线的慢回显占比);序列接口增加 anchor=latest。

  • 打包与部署(M6 的一部分):scripts/publish.sh(linux-musl-x64、linux-x64 在 NativeAOT SDK 容器里构建)、scripts/package.sh、packaging/(install.sh、systemd 单元、OpenWrt procd 脚本)、节点启动时的 OpenSSL 自检。在 Alpine、Debian、OpenWrt 官方 rootfs、带 systemd 的 Debian 容器里验证过。详见 docs/deployment.md。

未实现:

  • monitor-bench(M0/M2);arm64 构建(需要 arm64 主机或 CI)、真正的 OpenWrt 设备;udp_train 只支持 direction=rev;跨公网线路只试跑过一条(几分钟),还没有长期试跑。
  • 告警;定时调度和按需测试的长期峰值趋势;Windows Probe 没有 tcp_info;Probe 会话结束时最后 ≤10 秒的数据(不修,极端情况)。多个 Probe 同时连时,码率和包速率的预算按单个 Probe 会话计算,总负载是它的倍数,靠会话数上限(默认 8)约束。
  • fleet-updater、fleet-release、Fleet.Update、Fleet.Server.Releases、Fleet.Server.Sqlite(F2;Monitor 自己实现 IFleetStore)。
  • /api/admin/releases、/install.sh、/install.ps1(安装脚本返回 501,依赖打包 M6)。
  • M4 的校准(需要在真实线路上部署 Hysteria2 与 REALITY 对比)和 M5 的 30 天规模验证;模型评分曲线是 v1 的经验值。
  • 查询的 tz 只支持 UTC(其他值返回 400);probe.endpoint_changes 指标未进入注册表(计数在 Agent 运行时状态里)。