项目架构
NIE-SLA 把采集、探测、存储、展示与第三方扩展划分成不同信任区域。理解这些边界,才能避免把“VPS 在线”“Cloudflare 可达”和“外部节点延迟”当成同一种数据。不了解项目时先读项目概述。
核心组件
| 组件 | 运行位置 | 职责 |
|---|---|---|
| Rust Agent | 被监控 VPS | 秒级采样、TCP/HTTP 探测、按批次上传 |
| Latency Agent | 独立 Linux 节点 | 从不同网络位置探测公开 TCP 目标 |
| Worker | Cloudflare 边缘 | 路由、认证、调度、聚合、告警与公开 API |
| Durable Objects | Cloudflare | 区域探测协调与每 Agent 小时遥测缓冲 |
| D1 | Cloudflare | 配置、状态、聚合、事件与索引 |
| R2 | Cloudflare | 高频历史、状态快照、归档与主题包 |
| Worker Static Assets | Cloudflare | 公开状态页、管理后台与同源 API |
生产形态是一个 Worker 同源承载 API 与 Static Assets,不需要单独创建 Pages。公开一键部署仓库是脱敏发布源;生产维护保持 Worker、Frontend 与 Agent 的源码边界,禁止用旧归档或公开快照反向覆盖私有生产源。
数据链路
Rust Agent ──scoped token──> Worker ──> D1 / R2 ──> Public status
│
Cloudflare probe ─────────────────┤
│
Latency Agent ─scoped token───────┘Agent 的采样、上传、Ping 与更新检查由不同调度器负责。VPS 可以每秒采样,但 Worker 只按批次收到上传;网络短暂变慢不会阻塞下一次本地采样。
四类延迟与在线状态
| 数据源 | 发起位置 | 回答的问题 |
|---|---|---|
| Cloudflare 探测 | Worker / Durable Object | Cloudflare 边缘能否连接目标,延迟多少 |
| Agent 在线状态 | 被监控 VPS | 指标 Agent 最近是否持续上报 |
| Agent 网络探测 | 被监控 VPS | 该 VPS 到指定 TCP/HTTP 目标的网络质量 |
| 外部 Latency | 独立网络节点 | 额外地区或运营商到公开 TCP 目标的延迟 |
客户端必须保留来源标签。Agent 在线不代表 Cloudflare 探测成功;端口可达也不代表指标 Agent 在运行。
存储策略
系统不把每秒原始指标全部写入 D1:
- 当前状态与索引在 D1。
- 高频指标历史优先写入 R2。
- SLA 历史按固定桶聚合后写入 D1。
- 流量在当前周期行内累计,跨天时每台 Agent 封存一条每日账本;修改重置日按日账本重新汇总。
- 状态接口使用短缓存。
- 清理任务按周期运行,不在每次请求中扫描历史。
这样在保持公开状态更新频率的同时,限制 Worker 请求、D1 写入与 R2 操作量。
原始丢包与可选时序导出
R2 保存 Agent 上报的原始探测点。常规延迟曲线按公开 API 上限降采样;include_loss=1 用紧凑 runs 无损返回全部丢包时间,长期连续故障不需要在浏览器中展开成逐秒对象。
外部时序导出默认关闭。配置 TIMESERIES_EXPORT_URL 后,Worker 按 Agent 与完成小时从 R2 批量导出;TIMESERIES_EXPORT_FORMAT 可为 victoriametrics(默认)或 influx,可选 Bearer 凭据用 TIMESERIES_EXPORT_TOKEN。地址必须是含内嵌凭据的 HTTPS URL。这些值只允许通过 Worker Secret 或部署环境提供,不进入前端、Agent 命令、公开 API、备份或源码。
导出使用独立的有界重试标记。远端超时、限流或不可用时,R2 归档与 Agent ACK 保持成功;达到重试上限只放弃该次外部导出,不删除 R2 原始数据。默认未配置时,不增加外部请求,也不改变 100 台 VPS 的内置存储路径。
接口与信任边界
| 接口 | 认证 | 可执行操作 |
|---|---|---|
/api/v1/* | 无 | 读取脱敏后的公开状态与历史 |
/api/agent/* | 节点 scoped Token | 对应 Rust Agent 上报与读取策略 |
/api/latency-agent/* | 节点 scoped Token | Latency 节点取目标、上报与更新 |
| Admin API | 短期 Session,可叠加 TOTP | 修改配置、上传主题、查看管理数据 |
Canvas 主题与替代前端只能使用公开 v1 API。不得向主题传递管理员 Session、密码、TOTP、Agent 主 Token 或节点 scoped Token;插件运行时当前不开放。
密码与 GitHub OAuth 票据只用于登录端点。登录后后台使用短期 x-admin-session;密码不应保存为普通 API Token,也不应由替代前端代理。Agent 与 Latency 使用各节点 scoped Token,禁用节点后对应凭据不再有写入权限。
NodeQuality 图片边界
NQ 的网络质量与回程路由图片由 Worker 在认证任务完成后生成并上传。上传链路固定使用 S3 渠道且不设置目录,前端、Agent 与管理 API 都不能读取或覆盖上传地址、Token、渠道与目录。
- 上传地址、Token 与可选渠道名只能配置为 Cloudflare Worker Secret。
- 只有管理员创建、对应 Agent 凭据领取并成功回传的 NQ 任务触发上传。
- 没有浏览器设置、测试上传或任意文件上传接口。
- 公开 NQ JSON 只返回同源图片代理,真实上游地址只在 Worker 内部解析。
- 普通备份排除旧版图床元数据,敏感备份必须经过密码加密。
- 自部署默认调用固定官方受限 Broker,不需要图床凭据;共享凭据只存在于官方 Worker Secret,不进入源码、构建产物、教程或 Broker 请求。
Broker 只接受有界的 network/route 文本并在服务端重新渲染 SVG,用 D1 按来源与全局限流。这条边界让自部署用户零配置获得 NQ 图片备份,同时避免把共享图床变成任意文件上传 API。非官方实例的图床 Secret 不会覆盖固定公益链路。
四类 NQ 页签都保留原始 ANSI 内容。网络质量与回程路由在原文存在时使用历史分段渲染器,图床图片只为缺少原文的旧数据兜底。移动端使用固定紧凑等宽字号,弹窗外层只纵向滚动,超宽网络分段在当前内容区横向滚动;回程 hop 使用响应式网格。公开页与后台保持同一套规则。
当前状态与长期 SLA
Worker Cron 每分钟只负责轻量调度;健康目标默认每 15 分钟执行一次历史探测,故障目标进入约 2 分钟恢复队列,长期 SLA 与日格仍使用 5 分钟桶。next_probe_at 索引让调度只读取到期候选,不再每分钟扫描全部目标。FAST_STATUS_ENABLED 关闭时,主动探测的当前状态退回持久化桶粒度。
经济模式下,Agent 仍在本机每秒采样,但默认每 15 分钟批量上报一次;任务领取间隔为 10 分钟,普通升级策略检查为 24 小时。指标延迟最多约 15 分钟,故障恢复探测仍保持约 2 分钟,手动/强制升级不受普通检查间隔限制。
“公开页面最新状态”和“日格新增一格”不需要同一频率。集成端应读取 checked_at、updated_at 与来源字段,不要用数组长度推断 Agent 是否在线。
主题运行时
CSS 主题只加载校验过的样式文件。Canvas 主题运行在 sandbox="allow-scripts" iframe 中,没有同源权限,CSP 禁止直接联网、表单与顶层导航;数据由宿主通过受限消息协议提供。插件上传 API 与插件运行时均未开放。详见主题系统与安全与发布规范。