mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-09-29 14:06:36 +08:00
[优化] 文档更新
This commit is contained in:
@@ -9,10 +9,8 @@
|
||||
|
||||
* **[docs/guildline/development-constraints.md](./docs/guildline/development-constraints.md)**
|
||||
*作用:掌握核心后端/Agent/前端分层约束、数据模型规范、数据库迁移升级协议、API 与鉴权设计准则。*
|
||||
* **[docs/guildline/Guidelines.md](./docs/guildline/Guidelines.md)**
|
||||
* **[docs/guildline/Guidelines.md](docs/guildline/Role.md)**
|
||||
*作用:通用的 Go 后端开发与高质量编码准则,包括架构、并发、错误处理、安全及工作流程。*
|
||||
* **[docs/guildline/Project.md](./docs/guildline/Project.md)**
|
||||
*作用:针对 OpenFlare 后端特定的控制器参数解析、响应处理、纯净工具类与数据库逻辑完全隔离、Go 泛型切片去重及 JSON 序列化避坑细则。*
|
||||
|
||||
### 系统参阅文档 按需查阅
|
||||
* **[docs/reference/configuration.md](./docs/reference/configuration.md)**
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
# OpenFlare 特定项目开发准则 (Project Guidelines)
|
||||
|
||||
本文档定义了针对 **OpenFlare** 项目特定的后端开发约束、架构设计模式、GORM 数据库交互规范以及关键的 JSON 序列化避坑指南。所有参与项目后端开发的代码必须严格遵守。
|
||||
|
||||
---
|
||||
|
||||
## 1. 统一接口输入与响应处理(Controller 约束)
|
||||
|
||||
为了保证 API 的一致性,并消除控制器层中大量的样板代码,所有 Gin Controller 必须遵守以下规范:
|
||||
|
||||
### 1.1 参数解析与绑定
|
||||
- **URL ID 参数解析**:必须调用统一的 `parseIDParam(c)` 辅助函数。严禁手写 `strconv.ParseUint(c.Param("id"), ...)`。
|
||||
- **JSON 请求体绑定**:必须调用统一的 `bindJSON(c, &input)` 辅助函数。严禁手动调用 `c.ShouldBindJSON` 或 `json.NewDecoder` 并重复编写错误返回逻辑。
|
||||
|
||||
### 1.2 标准 API 响应
|
||||
- 所有控制器方法的返回必须统一使用 `respondSuccess`、`respondFailure`、`respondBadRequest` 等标准方法。
|
||||
- **严禁手写** `c.JSON(http.StatusOK, gin.H{...})`,以确保全局 API 响应字段结构(`success`/`message`/`data`)的百分之百一致。
|
||||
|
||||
> [!IMPORTANT]
|
||||
> 接口的入参解析与响应统一规范定义在 [openflare_server/controller/response.go](file:///Users/ryan/DEV/Go/OpenFlare/openflare_server/controller/response.go) 中。
|
||||
|
||||
---
|
||||
|
||||
## 2. 纯净工具类与数据库逻辑完全隔离(Utils 约束)
|
||||
|
||||
为了确保代码的可测试性、高内聚和低耦合,`utils/` 目录下的工具包必须保持纯净性:
|
||||
|
||||
### 2.1 无副作用与解耦原则
|
||||
- 所有底层客户端与外部服务对接包(如 `utils/acme` 证书操作、邮件发送、DNS 供应商对接等)**必须完全剥离数据库或 GORM 依赖**。
|
||||
- 工具包中严禁导入 `openflare/model` 包或直接访问数据库连接。它们应当只接受基础数据类型(如 `string`、`[]byte` 等)或本地无依赖结构体作为输入,并返回纯粹的计算或请求结果。
|
||||
|
||||
### 2.2 业务服务层(Service)职责
|
||||
- 业务服务层 `service/` 负责数据库实体的加载、组装、事务持久化,并将底层的具体网络或加密操作委托给 `utils/` 工具包。
|
||||
- 这样不仅保证了底层工具类的百分之百可单元测试性,也维护了清晰的系统分层。
|
||||
|
||||
---
|
||||
|
||||
## 3. Go 泛型切片去重与 JSON 序列化陷阱(Slice 约束)
|
||||
|
||||
在进行切片操作和去重时,必须使用泛型辅助函数,并注意 Go Slice 的空/零值在 JSON 序列化中的表现。
|
||||
|
||||
### 3.1 避免重复编写 map-seen 逻辑
|
||||
- 禁止在 `service/` 或 `model/` 中手写临时的 map-seen 去重样板代码。
|
||||
- 必须统一调用基于 Go 泛型实现的 [openflare_server/utils/slice.go](file:///Users/ryan/DEV/Go/OpenFlare/openflare_server/utils/slice.go) 中的 `utils.Unique()` 辅助函数。
|
||||
|
||||
### 3.2 关键的 JSON 序列化规则(Nil vs. Empty Slice)
|
||||
在 Go 中,未初始化的 `nil` 切片和已初始化的空切片 `[]T{}` 在内存中不同,它们在序列化为 JSON 时也有着决定性的区别:
|
||||
- **`nil` 切片**:序列化为 JSON `null`。
|
||||
- **空切片 (`make([]T, 0)`)**:序列化为 JSON `[]`。
|
||||
|
||||
> [!CAUTION]
|
||||
> **开发避坑准则**:
|
||||
> 1. GORM 数据库的很多 JSON/Array 字段(例如 `domain_cert_ids`、`upstreams` 等)或配置版本变更检测机制(如 `checksum` 计算和 `diff` 检测),要求空数组在 JSON 中必须表示为 `[]` 而非 `null`,否则会触发重复发布或解析失败的 bug。
|
||||
> 2. `utils.Unique` 必须具备 **Nil-Preservation(空值保留)** 特性:
|
||||
> - 如果传入的 Slice 是 `nil`,它必须返回 `nil`,以支持 `omitempty` 或在需要表示“缺失”的场景中输出 `null`。
|
||||
> - 如果传入的 Slice 不是 `nil`(即使长度为 0 或去重后长度为 0),它必须返回非 nil 的空切片 `make([]T, 0)`,以确保序列化为 `[]`。
|
||||
> 3. 所有类似的切片加工辅助函数都必须遵循此行为。
|
||||
@@ -13,7 +13,6 @@
|
||||
- 日志方式
|
||||
- 测试组织方式
|
||||
- 依赖注入方式
|
||||
- 现有编码风格
|
||||
|
||||
如果你不确定某个模块的职责,先通过代码上下文推断,不要随意新建重复模块。
|
||||
|
||||
@@ -43,12 +42,12 @@
|
||||
|
||||
3. 可维护性
|
||||
- 修改前先分析影响范围。
|
||||
- 尽量最小改动,不做无关重构。
|
||||
- 不改变公开 API、数据库结构、配置格式,除非任务明确要求。
|
||||
- 如果必须改变,要说明兼容性影响和迁移方案。
|
||||
- 删除代码前确认没有调用方。
|
||||
- 避免复制粘贴已有逻辑,应抽取到合适位置,但不要过度抽象。
|
||||
- 对复杂业务逻辑添加必要注释,解释“为什么”,不要注释显而易见的“是什么”。
|
||||
- 开发前先检查 utils、helpers 包,避免重复造轮子。
|
||||
|
||||
4. 测试要求
|
||||
- 新增业务逻辑必须补充单元测试。
|
||||
@@ -81,6 +80,8 @@
|
||||
- 日志中不要打印密码、token、密钥、身份证号等敏感数据。
|
||||
- 返回结构保持向后兼容。
|
||||
- HTTP 状态码要语义正确。
|
||||
- API 返回要有一致的格式,例如 { "code": 0, "message": "success", "data": {...} }。
|
||||
- API 返回统一使用封装的方法 response.go,不要直接构造响应。
|
||||
|
||||
8. 日志与可观测性
|
||||
- 关键路径要有必要日志。
|
||||
@@ -1,8 +1,6 @@
|
||||
# 开发约束
|
||||
|
||||
你会学到:OpenFlare 代码修改的准入标准、后端/Agent/前端分层约束、数据模型边界、API 约定、数据库迁移要求和测试交付基线。
|
||||
|
||||
本文档融合原开发规范、前端规范与开发计划。
|
||||
OpenFlare 代码修改的准入标准、后端/Agent/前端分层约束、数据模型边界、API 约定、数据库迁移要求和测试交付基线。
|
||||
|
||||
## 变更准入
|
||||
|
||||
@@ -74,46 +72,6 @@ Frontend:
|
||||
|
||||
* **禁止随意引入平台化新实体**:除非 [产品边界](../design/index.md) 设计发生调整并经评审。
|
||||
|
||||
* **业务唯一性保障**:
|
||||
* `proxy_routes.site_name` 作为业务唯一主标识。
|
||||
* `proxy_routes.domains` 中的各域名必须全局唯一,不可跨站点冲突,列表第一项视为主域名。
|
||||
* `nodes.node_id` 唯一标识节点(自动生成或由用户指定)。
|
||||
* `tunnels.tunnel_id` 唯一标识内网穿透客户端(格式 `tun-<32hex>`,自动生成)。
|
||||
|
||||
* **兼容字段处理**:遗留的 `proxy_routes.domain` 只能作为 `domains[0]` 的只读/兼容镜像,新代码不得以该字段为唯一业务输入。
|
||||
|
||||
* **多上游及 Keepalive**:单上游时应支持 base path/query 并在 `proxy_pass` 中正确补齐 URI;多上游负载均衡时仅允许纯 `scheme://host[:port]`。
|
||||
|
||||
* **证书映射**:证书绑定必须通过逐域名平行的 `domain_cert_ids` 字段精确保存,未绑定证书的域名不得参与 HTTPS 渲染。
|
||||
|
||||
* **版本快照一致性**:`config_versions` 必须保存版本发布时的完整快照及 checksum 校验码,确保渲染结果不可变且全局单激活版本。
|
||||
|
||||
* **外部账户唯一绑定**:第三方登录必须通过 `external_accounts` 映射至本地唯一用户,原 `users.github_id` 仅用于向后兼容迁移,任何新登录流程禁止以此为业务输入。
|
||||
|
||||
* **Tunnel 与上游关联**:
|
||||
* `proxy_routes.upstream_type = 'tunnel'` 时,必须指定 `tunnel_id`(关联到 `tunnels` 表)。
|
||||
* 必须指定 `tunnel_target_addr`(内网目标地址,如 `192.168.1.100:8080`)和 `tunnel_target_protocol`(`http` 或 `https`)。
|
||||
* 发布配置时,Server 自动将此上游渲染为 `http://127.0.0.1:{relay_vhost_port}`,Agent 依据 Host 头由 frps 路由。
|
||||
|
||||
* **Pages 与上游关联**:
|
||||
* `proxy_routes.upstream_type = 'pages'` 时,必须指定 `pages_project_id`。
|
||||
* 被引用的 Pages 项目必须启用,且必须存在当前激活部署。
|
||||
* Pages 项目可启用 SPA fallback 并配置站点内绝对回退路径(默认 `/index.html`);回退路径必须经 Server 校验后进入发布快照,不得直接拼接未校验输入到 OpenResty 配置。
|
||||
* Pages 部署包必须作为 Server 本地文件保存,数据库只保存部署元数据与文件清单;禁止把静态资源内容写入 `config_versions.support_files_json`。
|
||||
* 发布配置时,Server 将 Pages 上游渲染为 OpenResty `root` + `try_files` 静态服务,并保留网站规则已有的 HTTPS、WAF、PoW、Basic Auth、限流与缓存配置。
|
||||
|
||||
* **TunnelRelay 节点配置**:
|
||||
* `nodes.node_type = 'tunnel_relay'` 时,新增字段 `relay_bind_port`、`relay_vhost_http_port`、`relay_auth_token` 必须有合理默认值。
|
||||
* `relay_bind_port` 默认 7000,`relay_vhost_http_port` 默认 8080。
|
||||
* `relay_auth_token` 由 Server 自动生成(32 位随机字符串),不由用户输入。
|
||||
* 相对静态配置(如 `relay_agent_access_addr`、`relay_client_access_addr`)由 Relay 心跳下发,Server 可记录但不纳入版本化流。
|
||||
|
||||
* **Tunnel 客户端状态**:
|
||||
* `tunnels.status` 记录客户端在线/离线/待激活状态。
|
||||
* `tunnels.current_version` / `tunnels.current_checksum` 记录当前已应用的配置版本。
|
||||
* `tunnels.connected_relays` 以 JSON 数组形式存储已连接 Relay 的信息(relay_node_id、连接状态等)。
|
||||
* `last_seen_at`、`last_error` 用于调试和可观测性。
|
||||
|
||||
## 数据库迁移
|
||||
|
||||
任何涉及表结构、索引、列类型、分表规则或内部持久化元数据的修改,都必须同步提升数据库版本号。
|
||||
@@ -122,9 +80,7 @@ Frontend:
|
||||
|
||||
每次提升数据库版本号时,必须补充从上一版本升级到新版本的显式迁移方法。迁移方法必须包含升级后的校验逻辑;只有校验通过,才能写入新的数据库版本记录。
|
||||
|
||||
v1-v7 视为历史初始基线,不再维护逐版本升级文件。v8-v17 是旧升级框架的兼容迁移链,只保留在 `openflare_server/model/migrate` 目录中用于老库升级。旧库启动时必须先按旧框架升级到 `legacyMigrationTerminalVersion`,再桥接到 goose;不得为了整理文件而改变已发布 v8-v17 迁移的语义。
|
||||
|
||||
从 v17 之后,数据库升级统一使用 goose。新的 goose provider、桥接逻辑、注册入口和具体迁移文件必须全部放在 `openflare_server/model/goose` 包下,`openflare_server/model` 根包只保留纯净实体类、旧框架兼容适配和必要的上下文注入。每次新增数据库升级都必须新建一个单独的 Go 文件,文件名使用 `openflare_server/model/goose/goose_<timestamp>_<description>.go`,例如 `openflare_server/model/goose/goose_202606020001_add_node_capabilities_json.go`。迁移文件必须同时包含该版本的 goose migration 构造函数、升级逻辑和校验逻辑;`model/goose/migrations.go` 只能作为注册入口和公共构造工具,禁止把具体迁移逻辑集中堆放在该文件中。
|
||||
数据库升级统一使用 goose。新的 goose provider、桥接逻辑、注册入口和具体迁移文件必须全部放在 `openflare_server/model/goose` 包下,`openflare_server/model` 根包只保留纯净实体类、旧框架兼容适配和必要的上下文注入。每次新增数据库升级都必须新建一个单独的 Go 文件,文件名使用 `openflare_server/model/goose/goose_<timestamp>_<description>.go`,例如 `openflare_server/model/goose/goose_202606020001_add_node_capabilities_json.go`。迁移文件必须同时包含该版本的 goose migration 构造函数、升级逻辑和校验逻辑;`model/goose/migrations.go` 只能作为注册入口和公共构造工具,禁止把具体迁移逻辑集中堆放在该文件中。
|
||||
|
||||
执行数据库升级时必须按以下步骤完成:
|
||||
|
||||
@@ -135,13 +91,12 @@ v1-v7 视为历史初始基线,不再维护逐版本升级文件。v8-v17 是
|
||||
5. 在同一个单独迁移文件中写入升级后的校验逻辑。校验至少要覆盖新增表/字段/索引是否存在、关键默认数据是否存在、必要的数据回填是否成功。
|
||||
6. 如果新迁移需要新的公共 backfill 或校验辅助函数,优先放在该迁移文件中;只有多个迁移共同复用时,才放到 `openflare_server/model/goose` 包内的公共文件中。不要把新 goose 框架代码放回 `openflare_server/model` 根包。
|
||||
7. 补充迁移测试:至少覆盖从旧框架终点或上一 goose 版本升级后 schema version、字段/表结构、关键数据回填和校验结果。还应保留旧库从 v15/v17 桥接到 goose 的回归覆盖。
|
||||
8. 同步更新设计/开发文档;如果管理端 API、配置项或用户可见行为变化,还要同步更新对应指南、配置参考和 Swagger 文档。
|
||||
|
||||
新包启动后必须先检查数据库当前版本,再按顺序逐步升级到目标版本;禁止跳过中间升级步骤直接写目标版本。
|
||||
|
||||
空库初始化可以直接建立当前版本结构,但初始化完成后仍必须执行同版本校验,并落库当前数据库版本。
|
||||
|
||||
如果迁移失败或校验失败,启动流程必须中止,且不得提升数据库版本记录。涉及数据库版本变更的提交,必须补充对应的迁移测试或等效回归测试。
|
||||
如果迁移失败或校验失败,启动流程必须中止,确保数据库能够回滚。涉及数据库版本变更的提交,必须补充对应的迁移测试或等效回归测试。
|
||||
|
||||
## API 与鉴权
|
||||
|
||||
@@ -160,100 +115,25 @@ v1-v7 视为历史初始基线,不再维护逐版本升级文件。v8-v17 是
|
||||
* Agent API 固定放在 `/api/agent/*`,使用 `X-Agent-Token` 认证(节点专属 token)。
|
||||
* **Relay API** 固定放在 `/api/relay/*`,使用 `X-Agent-Token` 认证(同 TunnelRelay 节点)。
|
||||
- Server 通过 token + `/api/relay/*` 路径区分 Relay 请求。
|
||||
- Relay 心跳返回 frps 配置(bindPort、vhostHTTPPort、authToken)。
|
||||
- Relay 上报进程状态、连接数、proxy 列表等指标。
|
||||
* **Tunnel Client API** 固定放在 `/api/flared/*`,使用 `X-Tunnel-Token` 认证(独立的 tunnel_token)。
|
||||
- OpenFlared 使用 `tunnel_token` 与 Server 通信,独立于 Agent 认证体系。
|
||||
- Client 心跳返回 tunnel 配置版本摘要。
|
||||
- Client 可拉取完整配置(relay 列表 + frpc 代理定义)。
|
||||
- Client 上报配置应用结果。
|
||||
* **Admin Tunnel 管理 API** - `/api/tunnels/*`,要求管理端 `OPENFLARE_TOKEN`。
|
||||
* **Admin Tunnel 管理 API** - `/api/tunnels/*`。
|
||||
- CRUD tunnel 实体(创建、查询、更新、删除)。
|
||||
- Token 管理(生成、轮换)。
|
||||
- 强制同步(触发 Client 立即拉取新配置)。
|
||||
* **Admin Pages 管理 API** - `/api/pages/*`,要求管理端 `OPENFLARE_TOKEN`。
|
||||
* **Admin Pages 管理 API** - `/api/pages/*`。
|
||||
- CRUD Pages 项目,包括 SPA fallback 启用状态与回退路径。
|
||||
- 上传 zip 部署包、查看部署历史、激活部署、删除非激活部署。
|
||||
* **Agent Pages 下载 API** - `/api/agent/pages/*`,使用 `X-Agent-Token` 认证。
|
||||
- Agent 仅能按激活配置引用的部署 ID 拉取静态部署包,不提供任意文件读取或远程命令入口。
|
||||
* 总览与节点详情优先使用专用聚合接口。
|
||||
* 管理端变更类接口统一使用 `POST`;只读接口使用 `GET`。
|
||||
* 管理端登录成功后返回用户 token;管理端 API 只允许从 `OPENFLARE_TOKEN` 请求头读取登录凭证,不得通过 Cookie Session 放行。
|
||||
* 第三方登录统一通过认证源 API 进入,认证源管理接口必须要求 Root 级 `OPENFLARE_TOKEN`。
|
||||
* `/api/status` 只能返回已启用认证源的公开字段,不得返回 Client Secret。
|
||||
* 第三方账号未绑定且注册关闭时,应提供绑定已有账号流程,不得自动创建用户。
|
||||
* 系统仅单租户使用, 不得创建用户。
|
||||
* Agent/Relay/Client 正式请求统一使用对应的专属 token(`agent_token` / `relay_token`(即 agent_token) / `tunnel_token`)。
|
||||
* 首次接入 Agent 可使用全局 `discovery_token`;首次接入 Client 由 Server 生成 tunnel_token,直接用于部署命令。
|
||||
* Agent/Relay 请求头统一使用 `X-Agent-Token`;Client 请求头统一使用 `X-Tunnel-Token`。
|
||||
|
||||
禁止暴露远程 shell 或任意命令执行入口,禁止在日志中打印完整 Token,禁止绕过占位符约束保存不可渲染的主配置模板。
|
||||
|
||||
## 发布与运行
|
||||
|
||||
发布逻辑必须保持:
|
||||
|
||||
* 发布时读取全部启用的 `proxy_routes`。
|
||||
* 同时读取 OpenResty 主配置参数、反代性能参数与缓存参数。
|
||||
* 读取 WAF 规则组、规则组引用的 IP 组与网站绑定关系,并在发布快照中保存可回放数据。
|
||||
* 自动型 WAF IP 组只能由 Server 定时任务读取请求日志并执行 Expr 布尔规则,OpenResty Lua 与 Agent 不得直接访问请求日志库或执行自动挖掘逻辑。
|
||||
* 发布版本不得展开 WAF IP 组成员;Agent 必须通过独立的 IP 组 checksum 差异同步和 WebSocket 增量广播维护本地 `waf_ip_groups.json`。
|
||||
* **Pages 配置扩展**:区分上游类型,为 `upstream_type = 'pages'` 的代理规则生成 Pages 部署快照。
|
||||
* OpenResty 侧:将 Pages 上游渲染为本地静态目录 `root` 与 `try_files`,启用 SPA fallback 时使用项目配置的回退路径,不得渲染 `proxy_pass`。
|
||||
* Agent 侧:在应用 OpenResty 配置前,必须确保引用的 Pages 部署包已下载、checksum 校验通过并解压到 `pages_dir`。
|
||||
* **内网穿透配置扩展**:区分上游类型,为 `upstream_type = 'tunnel'` 的代理规则生成独立的 tunnel 配置数据。
|
||||
* OpenResty 侧:将 tunnel 上游自动渲染为 `http://127.0.0.1:{relay_vhost_port}`,必须保留原始 `Host` 请求头。
|
||||
* Tunnel 侧:为每个 Client 生成完整的 relay 列表与 frpc 代理定义(frpc proxy 配置)。
|
||||
* 生成完整 OpenResty 配置。
|
||||
* 计算 `checksum`。
|
||||
* 写入 `config_versions`(OpenResty 部分)+ 生成或更新 tunnel 配置版本数据。
|
||||
* 通过切换 `is_active` 激活版本。
|
||||
|
||||
版本约束:
|
||||
|
||||
* 版本号格式固定为 `YYYYMMDD-NNN`。
|
||||
* 同一版本号同时关联 OpenResty 配置与 Tunnel 配置,保证一致性。
|
||||
* 不在线修改历史版本。
|
||||
* 不做按节点分组的差异化版本。
|
||||
* 预览与 diff 是只读能力,不产生发布记录。
|
||||
|
||||
Agent 必须满足:
|
||||
|
||||
* 启动后读取或生成本地 `node_id`。
|
||||
* 周期性心跳与同步。
|
||||
* 常规同步优先依据 heartbeat 返回的版本摘要判断。
|
||||
* WS 连接升级开启且连接成功时,Agent 可通过 WS 接收激活版本摘要并立即同步;WS 失败或断开必须退回 HTTP heartbeat。
|
||||
* 发现新版本时先备份旧文件。
|
||||
* 写入主配置、路由配置与必要证书文件。
|
||||
* 写入 WAF/PoW 运行时配置,并确保 WAF Lua 资源由 Agent 统一管理。
|
||||
* 如果激活配置引用 Pages 部署,必须通过 Agent API 拉取部署包,校验配置快照中的 SHA-256 checksum,安全解压并原子切换本地当前部署目录;zip 路径不得逃逸 `pages_dir`,不得接受符号链接。
|
||||
* WAF IP 组同步必须按组增量更新,不得在每次心跳或每次同步中传输全部 IP 组。
|
||||
* 写入新配置后执行 `openresty -t -c <main_config_path>`,再 reload;reload 发现运行时未启动时允许直接启动 OpenResty。
|
||||
* 周期性运行时健康检查不得调用 `openresty -t`,避免健康探针触发 upstream 域名同步解析;应优先请求本地 `openresty_observability_port` 上的 `/openflare/stub_status`,以 HTTP `200 OK` 作为 OpenResty 主进程和 worker 正在提供服务的判断依据。
|
||||
* 新配置激活失败时必须先尝试用目标配置恢复运行,再回滚到旧配置并重新拉起 OpenResty。
|
||||
* 回滚后 OpenResty 恢复正常时上报警告;如果本地没有历史主配置可恢复,必须允许写入内置安全兜底配置并拉起对外只监听 `80` 端口、统一返回 `503` 的 OpenResty 运行态;兜底配置仍需保留本地 `stub_status` 健康检查入口。
|
||||
* 兜底运行态不得清除失败目标的阻断状态;应用记录必须能体现目标版本失败但 fallback runtime 已启动。存在历史主配置但回滚后仍无法恢复运行时上报失败。
|
||||
* 某个目标 `version + checksum` 一旦应用失败并回退,Agent 必须在本地状态中阻断该目标的重复应用。
|
||||
* Agent 维护本地 MaxMind mmdb 时,下载或刷新失败只能记录警告,不得阻断心跳、同步、配置应用或 OpenResty 健康检查。
|
||||
|
||||
OpenFlareRelay 必须满足:
|
||||
|
||||
* 启动后从 config 读取 Server 地址和 `agent_token`。
|
||||
* 周期性向 Server 发送心跳,获取 frps 配置(bindPort、vhostHTTPPort、authToken)。
|
||||
* 根据心跳响应生成 frps.toml,启动或更新 frps 进程。
|
||||
* 上报 frps 进程健康状态、连接数、proxy 数等指标。
|
||||
* frps 进程异常时自动重启,并上报失败信息。
|
||||
* 可选支持 WebSocket 升级连接,接收实时配置推送。
|
||||
|
||||
OpenFlared 必须满足:
|
||||
|
||||
* 启动后从 config 读取 Server 地址和 `tunnel_token`。
|
||||
* 周期性向 Server 发送心跳,获取 tunnel 配置版本摘要。
|
||||
* 发现新版本后拉取完整 tunnel 配置(relay 列表 + frpc 代理定义)。
|
||||
* 为每个 relay 生成独立 frpc.toml,启动新 frpc 进程或对已有进程执行热重载。
|
||||
* 上报每个 frpc 进程的健康状态与连接情况。
|
||||
* 配置应用失败时记录错误并上报,支持重试。
|
||||
* 可选支持 WebSocket 升级连接,接收实时配置变更通知。
|
||||
|
||||
## 前端请求、状态与类型
|
||||
|
||||
所有 API 请求必须统一经过 `lib/api/`:
|
||||
|
||||
Reference in New Issue
Block a user