docs: rewrite README and AGENTS.md etc..
This commit is contained in:
1 parent
cc64df3e70
commit
a9bf849697
22 files changed
+514
-665
No files matched your search
+35
-33
@@ -2,18 +2,18 @@
|
||||
|
||||
## 1. 目标
|
||||
|
||||
1. **三个独立项目加一个前端**:Probe、Agent、Backend 各自拥有解决方案,可以单独构建、测试和发布;Web 是独立的 Vite 项目(`web/`)。
|
||||
2. **通用能力只写一次**:TCP/QUIC Datagram/TLS/ICMP 采集积木(类似 iperf3 的能力,但只记录原始数据)放在 `MoShiro.Measurement` 中,Probe 和 Agent 共用;采集方法(Kind)由积木组合声明而成。
|
||||
3. **节点机制通用化**:注册、身份、连接、RPC、可靠上报、状态同步、宿主,由与业务无关的 **Fleet** 框架提供(见 [../backend/fleet/README.md](../../backend/fleet/README.md))。MoShiro 只写业务,其他产品也可以复用 Fleet。
|
||||
4. **改一处,整条链路受益**:协议、原始数据格式、测试方案、指标、错误码、版本号、编译设置、代码风格都只有**一个真源**。改动之后,下游要么自动更新,要么在编译期或 CI 中直接报错。
|
||||
5. **模块化**:Probe/Agent 由可插拔的模块组成;Backend 按层分成多个项目,层之间的依赖在编译期强制。
|
||||
6. **Probe/Agent 轻量**:运行时只依赖 BCL 和仓库内的库,不引用任何 NuGet 包。
|
||||
1. 三个独立项目加一个前端:Probe、Agent、Backend 各自拥有解决方案,可以单独构建、测试和发布;Web 是独立的 Vite 项目(`web/`)。
|
||||
2. 通用能力只写一次:TCP/QUIC Datagram/TLS/ICMP 采集积木(类似 iperf3 的能力,但只记录原始数据)放在 `MoShiro.Measurement` 中,Probe 和 Agent 共用;采集方法(Kind)由积木组合声明而成。
|
||||
3. 节点机制通用化:注册、身份、连接、RPC、可靠上报、状态同步、宿主,由与业务无关的 Fleet 框架提供(见 [Fleet 文档](../../backend/fleet/README.md))。MoShiro 只写业务,其他产品也可以复用 Fleet。
|
||||
4. 单一真源:协议、原始数据格式、测试方案、指标、错误码、版本号、编译设置、代码风格都只有一处定义,改动后下游自动更新,或在编译期、CI 中报错。
|
||||
5. 模块化:Probe/Agent 由可插拔的模块组成;Backend 按层分成多个项目,层之间的依赖在编译期强制。
|
||||
6. 轻量:运行时只依赖 BCL 和仓库内的库,不引用任何 NuGet 包。
|
||||
|
||||
## 2. 仓库布局
|
||||
|
||||
```text
|
||||
moshiro/
|
||||
├─ README.md TODO.md AGENTS.md .gitignore
|
||||
├─ README.md AGENTS.md .gitignore
|
||||
├─ docs/
|
||||
├─ scripts/ # publish / package / smoke / stability 等脚本
|
||||
├─ packaging/ # install.sh、systemd 单元、OpenWrt 文件
|
||||
@@ -32,8 +32,8 @@ moshiro/
|
||||
│ ├─ tools/ fleet-enroll
|
||||
│ └─ tests/
|
||||
├─ shared/ # MoShiro 自己的共享库
|
||||
│ ├─ MoShiro.Protocol/ # 契约真源:Kind/Plan 目录、任务集、moshiro.* 方法、UDP 包、RawChunk、错误码
|
||||
│ ├─ MoShiro.Measurement/ # 采集引擎:积木、Recorder、任务调和(见 measurement.md)
|
||||
│ ├─ MoShiro.Protocol/ # 契约真源:Kind 目录、任务集、moshiro.* 方法、测量包、RawChunk、错误码
|
||||
│ ├─ MoShiro.Measurement/ # 采集引擎:积木、行表、合并、预算(见 measurement.md)
|
||||
│ └─ tests/
|
||||
├─ probe/ src/MoShiro.Probe/ tests/ # 家宽端采集器
|
||||
├─ agent/ src/MoShiro.Agent/ tests/ # VPS 端采集器
|
||||
@@ -46,7 +46,7 @@ moshiro/
|
||||
│ └─ MoShiro.Backend.Storage.Sqlite/ # 端口接口的实现,同时实现 IFleetStore
|
||||
├─ tests/
|
||||
├─ openapi/v1.json # 构建生成并提交
|
||||
└─ MoShiro.Backend.slnx
|
||||
└─ (解决方案见 backend/MoShiro.slnx)
|
||||
```
|
||||
|
||||
节点机器上的发布物是两个独立进程,注册和采集分开:`fleet-enroll`(一次性运行)和 `moshiro-agent`(或 `moshiro-probe`,常驻)。更新:Quadlet 装的 Agent、Probe 由节点退出后 systemd 重新拉镜像,Backend 和一行脚本装的节点由宿主机上的 `moshiro-update` 完成,见 [deployment.md](../ops/deployment.md)。
|
||||
@@ -104,28 +104,30 @@ Web ──> openapi/v1.json
|
||||
|
||||
```text
|
||||
MoShiro.Protocol/
|
||||
├─ ProtocolLimits MoShiroErrors(在 Fleet 错误码基础上扩展)
|
||||
├─ Ids/ AgentId(= Fleet NodeId)、ProbeId、TaskId、TestId、ChunkId、StreamId
|
||||
├─ ProtocolLimits MoShiroErrors(在 Fleet 错误码基础上扩展) IpVersions PublicAddress Ipv6Diagnostic
|
||||
├─ Ids/ AgentId(= Fleet NodeId)、ProbeId、TaskId、TestId
|
||||
├─ Catalog/
|
||||
│ ├─ Kinds/ KindSpec 声明(积木组合 + ParamSpec + 记录列 + 预算)
|
||||
│ ├─ Kinds/ Kind 声明(积木组合 + ParamSpec + 记录列 + 预算)
|
||||
│ ├─ KindSpec Kind 与记录流(StreamSpec)的类型定义
|
||||
│ └─ ParamSpec 参数定义(类型、默认值、上下限),节点与 Backend 共用同一套校验
|
||||
├─ Tasks/ TaskSet(Fleet 期望状态的文档类型)、调和结果
|
||||
├─ Rpc/ moshiro.* 方法名、params/result、二进制通道号(从 16 开始)
|
||||
├─ Wire/ QUIC Datagram 测量包
|
||||
├─ Rpc/ moshiro.* 方法表与 params/result、二进制通道号(从 16 开始)
|
||||
├─ Wire/ QUIC Datagram 测量包、TCP 数据连接首帧
|
||||
└─ Raw/ 自描述 RawChunk:头部、列类型、列编解码、Brotli、crc32c
|
||||
```
|
||||
|
||||
累加器、直方图等统计类型**不在 Protocol 中**,只属于 `Backend.Analysis`。
|
||||
累加器、直方图等统计类型只属于 `Backend.Analysis`,不在 Protocol 中。测试方案(Plan)只存在于 Backend(`Application/Tests/Plans.cs`)。
|
||||
|
||||
### 4.3 MoShiro.Measurement(采集引擎)
|
||||
|
||||
包含:
|
||||
|
||||
- 积木:Transport、Pacer、Payload、Behavior、Sampler;
|
||||
- 根据列定义自动生成的 Recorder;
|
||||
- `KindAssembler`;
|
||||
- `TaskReconciler`(实现 Fleet 的 `IStateReconciler<TaskSet>`);
|
||||
- `BudgetGuard`。
|
||||
- 按 Kind 声明驱动的行表(`RowStore`)与列块合并(`FragmentMerger`、`ChunkFinalizer`);
|
||||
- `BlockCatalog`:Kind 到拨号方 / 监听方积木的映射;
|
||||
- `BudgetGuard`:参数校验与本地硬上限。
|
||||
|
||||
任务调和在 Agent 的 `TaskManager` 与 Probe 中完成。
|
||||
|
||||
详见 [measurement.md](../design/measurement.md) 第 6 节。
|
||||
|
||||
@@ -133,7 +135,7 @@ MoShiro.Protocol/
|
||||
|
||||
### 5.1 Agent 与 Probe:组装
|
||||
|
||||
节点的组装点是 `AgentApp` 和 `ProbeApp`:在构造函数里**显式组装**,不使用 DI 容器,也不做反射扫描;没有全局状态,测试可以在同一进程里启动多个。连接、认证、重连、发件箱、状态同步都由 Fleet 提供,MoShiro 只写业务:
|
||||
节点的组装点是 `AgentApp` 和 `ProbeApp`:在构造函数里显式组装,不使用 DI 容器,也不做反射扫描;没有全局状态,测试可以在同一进程里启动多个。连接、认证、重连、发件箱、状态同步都由 Fleet 提供,MoShiro 只写业务:
|
||||
|
||||
```text
|
||||
AgentApp Probe(ProbeApp)
|
||||
@@ -149,7 +151,7 @@ AgentApp Probe(ProbeApp)
|
||||
|
||||
模块之间通过构造函数传入的接口或 `Channel<T>` 通信,禁止通过静态全局状态共享数据。
|
||||
|
||||
**新增 RPC 方法**:在 `MoShiro.Protocol/Rpc` 中定义 params/result,然后在组装处加一行 `.On(Methods.X, HandleX)`。
|
||||
新增 RPC 方法:在 `MoShiro.Protocol/Rpc` 中定义 params/result,然后在组装处加一行 `.On(Methods.X, HandleX)`。
|
||||
|
||||
### 5.2 Backend:分层与 API 层
|
||||
|
||||
@@ -167,8 +169,8 @@ AgentApp Probe(ProbeApp)
|
||||
┌─────────────────────────────────────────────────────────┐ ┌───────────────────┴──┐
|
||||
│ Backend.Application │───>│ LiveHub(Application)│
|
||||
│ Agents · Probe · Tasks(有效任务集的计算与下发) │ │ 内存快照 + 主题订阅 │
|
||||
│ Tests · Ingest(chunk → 存储 → 分析队列)· SeriesQuery │ └──────────────────────┘
|
||||
│ AnalysisScheduler · Downsampler · Auth · Releases 视图 │ 调用 ─> Backend.Analysis
|
||||
│ Tests · Ingest(chunk → 存储 → 分析队列) │ └──────────────────────┘
|
||||
│ Analysis(AnalysisScheduler 等)· Query · Auth · Updates │ 调用 ─> Backend.Analysis
|
||||
└───────────────────────────▲─────────────────────────────┘ 纯计算:算子/指标/模型
|
||||
│ 实现端口
|
||||
┌───────────────────────────┴─────────────────────────────┐
|
||||
@@ -181,9 +183,9 @@ AgentApp Probe(ProbeApp)
|
||||
|
||||
规则:
|
||||
|
||||
- **Api 不能引用 Storage**(编译期保证);Api 和 Gateway 只调用 Application。
|
||||
- Application 返回 `Result<T>`。**错误码到 HTTP 状态的映射只在 Api 层做一次**(`ErrorCodeHttpMap`);到 JSON-RPC 错误的映射由 Fleet.Rpc 统一完成。
|
||||
- Api 层按调用方分目录:`Public/`、`Admin/`,公共部分放在 `Common/`(分页、ETag、认证过滤器、ProblemFactory、`EndpointConventions`)。每类资源一个端点文件,新增资源时在 `ApiModule.Map` 中加一行。
|
||||
- Api 不能引用 Storage(编译期保证);Api 和 Gateway 只调用 Application。
|
||||
- Application 返回 `Result<T>`。错误码到 HTTP 状态的映射只在 Api 层做一次(`ErrorCodeHttpMap`);到 JSON-RPC 错误的映射由 Fleet.Rpc 统一完成。
|
||||
- Api 层按调用方分目录:`Public/`、`Admin/`,公共部分放在 `Common/`(分页、ETag、认证过滤器、Problems、`EndpointConventions`)。每类资源一个端点文件,新增资源时在 `ApiModule.Map` 中加一行。
|
||||
- 注册端点、签名认证、连接注册表、状态推送、收件箱 ACK 都来自 Fleet(`MapFleetEnrollment`、`MapFleetLink`)。MoShiro 只提供:
|
||||
- `IFleetStore` 的实现;
|
||||
- `TaskSet` 的状态提供者;
|
||||
@@ -193,7 +195,7 @@ AgentApp Probe(ProbeApp)
|
||||
- 请求校验:简单字段约束使用 .NET 10 内置的 Minimal API 校验;任务参数统一用 `ParamSpec` 校验(与节点共用);跨字段规则放在 Application 层。
|
||||
- Backend 使用 ASP.NET Core 自带的 DI 容器,只在组合根显式注册。
|
||||
|
||||
Backend.Analysis 只依赖 MoShiro.Protocol 和 Fleet.Core,没有 I/O,可以单独做成离线 CLI 使用。
|
||||
Backend.Analysis 只依赖 MoShiro.Protocol 和 Fleet.Core,没有 I/O。
|
||||
|
||||
Backend 允许的包:ASP.NET Core 共享框架、`Microsoft.Data.Sqlite`、`Microsoft.AspNetCore.OpenApi`、`Microsoft.Extensions.ApiDescription.Server`(仅构建期使用)。
|
||||
|
||||
@@ -210,7 +212,7 @@ Backend 允许的包:ASP.NET Core 共享框架、`Microsoft.Data.Sqlite`、`Mi
|
||||
|
||||
## 7. 轻量预算
|
||||
|
||||
M0 阶段先测出基线,之后作为 CI 的回归门槛(超出 10% 即失败):
|
||||
体积和内存目标如下,表中「实测」为某次测量值:
|
||||
|
||||
| 程序 | 发布体积 | 空闲常驻内存 | 负载 |
|
||||
| --- | --- | --- | --- |
|
||||
@@ -234,14 +236,14 @@ M0 阶段先测出基线,之后作为 CI 的回归门槛(超出 10% 即失
|
||||
| --- | --- | --- |
|
||||
| Agent | `linux-x64`、`linux-arm64` | VPS |
|
||||
| Probe | `linux-x64`、`linux-arm64`、`win-x64` | 普通 PC 或服务器 |
|
||||
| Probe(OpenWrt) | `linux-musl-x64`、`linux-musl-arm64` | 正式支持;`linux-musl-arm`(armv7)视 M0 的工具链验证结果决定是否支持 |
|
||||
| Probe(OpenWrt) | `linux-musl-x64`、`linux-musl-arm64` | 正式支持;`linux-musl-arm`(armv7)视工具链验证结果决定是否支持 |
|
||||
| fleet-enroll | 与所在节点相同 | |
|
||||
| Backend | `linux-x64`、`linux-arm64`、`win-x64` | |
|
||||
|
||||
- **MIPS 不支持**(NativeAOT 没有 MIPS 目标)。使用 MIPS 路由器(例如 MT7621)时,把 Probe 运行在局域网内的其他设备上,比如 NAS、树莓派或 PC,测量结果同样代表这条家宽。
|
||||
- MIPS 不支持(NativeAOT 没有 MIPS 目标)。使用 MIPS 路由器(例如 MT7621)时,把 Probe 运行在局域网内的其他设备上,比如 NAS、树莓派或 PC,测量结果同样代表这条家宽。
|
||||
- NativeAOT 需要目标平台的原生工具链:musl 目标在 Alpine 容器中构建,arm64 使用交叉编译镜像。CI 矩阵为 Windows、Linux glibc、Linux musl。
|
||||
- `scripts/publish.sh <probe|agent|backend|fleet-enroll> <rid>` 输出到 `backend/artifacts/publish/<project>/<rid>/`。
|
||||
- 容器镜像由 CI 构建并对镜像 digest 签名,节点的宿主机更新器验签后更新,见 [deployment.md](../ops/deployment.md);纯二进制节点的更新见 [TODO.md](../../TODO.md)。
|
||||
- 容器镜像由 CI 构建并对镜像 digest 签名,节点的宿主机更新器验签后更新,见 [deployment.md](../ops/deployment.md);纯二进制节点的更新见 [路线图](../roadmap.md)。
|
||||
- Linux 上 TLS 依赖系统 OpenSSL(`libssl.so.3`)。
|
||||
|
||||
### 8.1 OpenWrt 上的 Probe
|
||||
@@ -256,7 +258,7 @@ M0 阶段先测出基线,之后作为 CI 的回归门槛(超出 10% 即失
|
||||
| 内存 | 预算 ≤ 32 MB,适合 ≥ 256 MB 内存的路由器;在本地配置中限制重负载测试的码率(`limits.max_test_mbps`),防止路由器 CPU 成为瓶颈,反过来影响测量结果 |
|
||||
| 测量偏差 | Probe 运行在网关上时,自己没有 NAT;一旦路由器 CPU 饱和,结果就会失真。因此 Probe 在 `moshiro.event` 中上报自身的 CPU 繁忙标记(仅进程级别),分析层据此标注置信说明 |
|
||||
| 打包 | 提供 `tar.gz` 和 procd 脚本;包格式(ipk 或 apk)按目标 OpenWrt 版本提供 |
|
||||
| 更新 | 纯二进制节点的更新器还没有实现([TODO.md](../../TODO.md));实现时 `keep_versions = 1`,下载前检查剩余空间,避免写满闪存 |
|
||||
| 更新 | 纯二进制节点的更新器还没有实现([路线图](../roadmap.md));实现时 `keep_versions = 1`,下载前检查剩余空间,避免写满闪存 |
|
||||
|
||||
## 9. Web
|
||||
|
||||
|
||||
Reference in new issue
Block a user