287 lines
11 KiB
Markdown
287 lines
11 KiB
Markdown
# 架构设计
|
||
|
||
> *“代码定义了它如何工作,架构定义了它如何活着。”*
|
||
|
||
---
|
||
|
||
## 架构总览
|
||
|
||
frpc-console 是一个**轻量级生命周期管理工具**,它的架构设计围绕着三个核心目标:
|
||
|
||
1. **低资源占用** — 在边缘设备上也能运行
|
||
2. **高可靠性** — 面板可挂,业务不能停
|
||
3. **零依赖部署** — 单一二进制,开箱即用
|
||
|
||
|
||
### 整体架构图
|
||
|
||
```mermaid
|
||
graph TB
|
||
subgraph User["用户侧"]
|
||
Browser["浏览器"]
|
||
CLI["命令行"]
|
||
end
|
||
|
||
subgraph Console["frpc-console"]
|
||
WebUI["Web UI<br/>(Vue 3 + 深色磨砂玻璃)"]
|
||
APIServer["API Server<br/>(Gin)"]
|
||
Lifecycle["生命周期管理器"]
|
||
ConfigMgr["配置管理器<br/>(TOML 解析/生成)"]
|
||
ProcessMgr["进程管理器<br/>(SetSid / PID 1 接管)"]
|
||
DB["SQLite<br/>(用户/隧道/配置)"]
|
||
Static["静态资源<br/>(内嵌)"]
|
||
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) — 二进制部署详细步骤 |