# 架构设计 > *“代码定义了它如何工作,架构定义了它如何活着。”* --- ## 架构总览 frpc-console 是一个**轻量级生命周期管理工具**,它的架构设计围绕着三个核心目标: 1. **低资源占用** — 在边缘设备上也能运行 2. **高可靠性** — 面板可挂,业务不能停 3. **零依赖部署** — 单一二进制,开箱即用 ### 整体架构图 ```mermaid graph TB subgraph User["用户侧"] Browser["浏览器"] CLI["命令行"] end subgraph Console["frpc-console"] WebUI["Web UI
(Vue 3 + 深色磨砂玻璃)"] APIServer["API Server
(Gin)"] Lifecycle["生命周期管理器"] ConfigMgr["配置管理器
(TOML 解析/生成)"] ProcessMgr["进程管理器
(SetSid / PID 1 接管)"] DB["SQLite
(用户/隧道/配置)"] Static["静态资源
(内嵌)"] end subgraph FRP["被管理对象"] FRPC["frpc 进程"] TOML["frpc.toml"] end Browser --> WebUI CLI --> APIServer WebUI --> APIServer APIServer --> DB APIServer --> ConfigMgr ConfigMgr --> TOML APIServer --> Lifecycle Lifecycle --> ProcessMgr ProcessMgr --> FRPC FRPC --> TOML Static -.-> WebUI ``` > **说明:** `Static`(前端静态资源)在编译时通过 `embed` 直接打包进二进制,运行时无需额外加载。因此图中以虚线表示其与 WebUI 的关联,且不占用独立部署单元。 --- ## 部署模型 frpc-console 支持两种部署模型,架构核心逻辑完全一致,只是运行环境不同。 ### 二进制部署模型 ``` ┌──────────────────────────────────────────┐ │ 操作系统 (Linux/Windows) │ │ │ │ ┌────────────────────────────────────┐ │ │ │ frpc-console │ │ │ │ ┌──────────────────────────────┐ │ │ │ │ │ Web UI │ API Server │ │ │ │ │ ├──────────────────────────────┤ │ │ │ │ │ 生命周期管理 / 配置管理 │ │ │ │ │ └──────────┬───────────────────┘ │ │ │ └─────────────┼──────────────────────┘ │ │ │ SetSid + 独立会话 │ │ ▼ │ │ ┌────────────────────────────────────┐ │ │ │ frpc 子进程 │ │ │ │ (被 PID 1 接管,独立生命周期) │ │ │ └────────────────────────────────────┘ │ │ │ │ ┌────────────────────────────────────┐ │ │ │ 数据目录: /opt/frpc-console/data │ │ │ │ ├── frpc-console.db │ │ │ │ ├── frpc.toml │ │ │ │ ├── frpc (二进制) │ │ │ │ ├── frpc.pid │ │ │ │ └── version.ini │ │ │ └────────────────────────────────────┘ │ └──────────────────────────────────────────┘ ``` **关键机制:** - frpc-console 启动时,通过 `SetSid` 为 frpc 创建**独立会话** - frpc 进程完全脱离父进程的生命周期控制 - 即使 console 崩溃或被 kill,frpc 会被 init(PID 1)接管,继续运行 ### Docker 部署模型 ``` ┌──────────────────────────────────────────┐ │ Docker Host │ │ │ │ ┌────────────────────────────────────┐ │ │ │ Container: frpc-console │ │ │ │ ┌──────────────────────────────┐ │ │ │ │ │ Web UI │ API Server │ │ │ │ │ ├──────────────────────────────┤ │ │ │ │ │ 生命周期管理 / 配置管理 │ │ │ │ │ └──────────┬───────────────────┘ │ │ │ │ │ 启动 frpc │ │ │ │ ▼ │ │ │ │ ┌──────────────────────────────┐ │ │ │ │ │ frpc 子进程 (容器内) │ │ │ │ │ └──────────────────────────────┘ │ │ │ └──────────────┬─────────────────────┘ │ │ │ Volume 挂载 │ │ ▼ │ │ ┌────────────────────────────────────┐ │ │ │ 数据卷: /opt/frpc-console/data │ │ │ │ ├── frpc-console.db │ │ │ │ ├── frpc.toml │ │ │ │ ├── frpc.pid │ │ │ │ └── version.ini │ │ │ └────────────────────────────────────┘ │ │ │ │ 重启策略: --restart=always │ └──────────────────────────────────────────┘ ``` **关键机制:** - 容器配置 `--restart=always`,console 退出时 Docker 自动重启 - 数据目录通过 Volume 挂载持久化 - 容器重启后自动重新拉起 frpc --- ## 核心模块 ### 1. Web UI(前端) - **框架:** Vue 3 - **风格:** 深色磨砂玻璃视觉 - **设计原则:** 需要时清晰易用,不需要时不打扰 - **构建产物:** 静态资源通过 Go embed 内嵌于二进制 ### 2. API Server - **框架:** Gin - **认证:** Session / JWT - **职责:** 提供 RESTful API,处理前端请求 ### 3. 生命周期管理器 负责 frpc 进程的完整生命周期: | 操作 | 行为 | |---|---| | 启动 | 根据当前 frpc.toml 启动 frpc 进程 | | 停止 | 向 frpc 发送终止信号 | | 重启 | 停止 → 重新加载配置 → 启动 | | 状态检查 | 读取 PID 文件,验证进程是否存在 | | 热加载 | 修改配置后自动重启 frpc(无需手动操作) | ### 4. 配置管理器 - 解析和生成 TOML 格式的 frp 配置文件 - 支持从现有 frpc.toml 导入 - 修改配置后自动触发重启 ### 5. 进程管理器 - 通过 `SetSid` 创建独立会话(Linux) - frpc 二进制内置在部署包中,无需额外下载 - 记录 PID 到文件,用于状态检查和进程管理 - Windows 版本使用相应的进程管理 API ### 6. SQLite 数据库 - **表结构:** - `users` — 管理员账户 - `tunnels` — 隧道配置 - `configs` — 全局配置 - **备份机制:** 部署脚本在降级前自动备份数据库文件 - **位置:** `data/frpc-console.db` --- ## 关键交互流程 ### 启动流程 ```mermaid sequenceDiagram participant User participant Console participant FRPC User->>Console: 启动 frpc-console Console->>Console: 读取 data/frpc.toml alt 配置文件存在 Console->>FRPC: 启动 frpc (SetSid) FRPC-->>Console: PID 写入 frpc.pid Console-->>User: 服务就绪 else 配置文件不存在 Console-->>User: 等待 WebUI 导入配置 User->>Console: WebUI 导入 frpc.toml Console->>FRPC: 启动 frpc end ``` ### 配置更新流程 ```mermaid sequenceDiagram participant User participant WebUI participant API participant ConfigMgr participant FRPC User->>WebUI: 修改隧道配置 WebUI->>API: PUT /api/tunnels/:id API->>ConfigMgr: 更新配置 ConfigMgr->>ConfigMgr: 写入 data/frpc.toml ConfigMgr-->>API: 配置已更新 API-->>WebUI: 200 OK API->>FRPC: 重启 frpc (热加载) FRPC-->>API: 启动成功 ``` --- ## 资源边界 ### 运行时资源 | 资源 | 典型值 | 说明 | |---|---|---| | CPU(idle) | ~0% | 无后台轮询 | | 内存(idle) | < 20MB | 无额外守护进程 | | 存储(二进制) | ~15MB | 静态编译,无依赖 | | 存储(数据) | < 1MB | SQLite + 配置文件 | > 真实设备实测数据见 [工程设计哲学 - 稳定性与可观测性](./engineering-philosophy.md#稳定性与可观测性) ### 文件系统布局 ``` /opt/frpc-console/ # 默认部署目录 ├── data/ # 数据目录(持久化) │ ├── frpc-console.db # SQLite 数据库 │ ├── frpc.toml # 当前 frpc 配置 │ ├── frpc # FRP 二进制(内置) │ ├── frpc.pid # frpc 进程 PID │ ├── frpc.log # frpc 日志(可选) │ └── version.ini # 当前版本标识 ├── frpc-console # 主二进制(二进制部署) └── .old_backup_* # 旧版本备份(迁移时生成) ``` --- ## 架构演进 当前架构不是一次性设计完成的,而是经历了以下阶段: 1. **最初**:一个简单的 Web UI,通过命令行调用 frpc 2. **发现问题**:SSH 断开后 frpc 也跟着退出 → 引入 SetSid 3. **发现问题**:配置文件修改需要手动重启 → 引入热加载 4. **发现问题**:ARMHF 设备跑不动 Docker → 引入二进制部署 5. **发现问题**:边缘设备内存不足 → 优化运行时内存占用 6. **发现问题**:更新时数据丢失 → 引入事务性部署脚本 7. **持续演化中**:每次真实部署都可能带来新的架构调整 --- ## 相关文档 - [工程设计哲学](./engineering-philosophy.md) — 架构决策背后的设计原则 - [设计决策记录](./design-decisions.md) — 每个“为什么”的详细记录 - [边缘节点部署](./edge-node.md) — 在受限环境中的架构适配 - [更新策略](./update-strategy.md) — 版本管理和升级机制 - [部署指南](./INSTALL_DOCKER.md) — Docker 部署详细步骤 - [二进制安装指南](./INSTALL_BINARY.md) — 二进制部署详细步骤