Files
MoShiro/docs/roadmap.md
T
justme 48072737c9 feat!: probes connect to the backend directly
A probe now links to the backend like an agent (probe.json carries the
server address). The backend sends the agent list as desired state and the
probe reports its platform and build in its own hello. The agent no longer
relays the list or the probe platform. Existing probes must be re-created.
2026-10-06 22:25:16 +08:00

111 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 里程碑
每个里程碑都以“可运行、可验证”作为完成标准;可执行程序在各自的目标 RID 上(见 [project-layout.md](project-layout.md) 第 9 节,Probe 包括 `linux-musl-x64` 和 `linux-musl-arm64`)的 NativeAOT 发布必须通过,并且零 AOT/trim 警告。
## M0 骨架
- 按 [project-layout.md](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.*` 方法、`probe_agents` 期望状态(Probe 直连面板)同步。
- 段文件与索引、发件箱 ACK、去重、缺口;管理员账号、Cookie 会话、API 令牌;`/api/admin` 中的节点、令牌、Probe 身份、任务管理。
**验收**:用一行安装命令部署一台新 VPS,自动注册 → 自动生成线路任务 → Probe 自动连接 → 1 分钟内在 `/api/admin` 中看到它的原始块。整个过程不需要手工配置。
## M4 分析层与实时
- 累加器、算子、首批 `MetricDef`、`base`/`mc`/`hy2`/`reality` 模型 v1;流式路径与持久路径;降采样;指标指纹与回填。
- 查询([query.md](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 列表(由面板经 Fleet 长连接直接下发,写回 `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 运行时状态里)。