168 lines
4.3 KiB
Markdown
168 lines
4.3 KiB
Markdown
# 设计决策
|
||
|
||
> *“这不是 API 文档,这是设计记录。它回答的不是‘怎么用’,而是‘为什么会变成这样’。”*
|
||
|
||
---
|
||
|
||
## 关于这份文档
|
||
|
||
frpc-console 的许多设计,如果只看最终结果,可能会让人觉得“奇怪”或“不按常理出牌”。
|
||
|
||
这份文档记录的就是这些“奇怪”背后的原因。
|
||
|
||
每一个决策,都来自真实部署中遇到的问题——而不是预先的设计。
|
||
|
||
---
|
||
|
||
## 为什么叫 Console,而不是 Manager?
|
||
|
||
这个命名不是随意选的。
|
||
|
||
| | Manager | Console |
|
||
|---|---|---|
|
||
| 暗示 | 管理权、控制中心 | 入口、操作界面 |
|
||
| 角色 | 大脑 | 工具 |
|
||
| 依赖关系 | 业务依赖 Manager | Console 依赖业务 |
|
||
|
||
**结论:**
|
||
|
||
frpc-console 不接管 FRP,不成为 FRP 的依赖。它只是一个入口,让你在需要的时候操作 FRP。
|
||
|
||
用完之后,关闭浏览器,FRP 还在跑。
|
||
|
||
这就是 Console 和 Manager 的区别。
|
||
|
||
---
|
||
|
||
## 为什么没有 CI/CD?
|
||
|
||
这个项目没有复杂的 CI/CD 发布流程。不是做不到,而是选择不做。
|
||
|
||
**原因:**
|
||
|
||
- CI/CD 在云端跑,部署在真实环境跑。两者之间隔着一个“信任”的黑洞。
|
||
- 如果发布流程和用户安装流程是两套不同的路径,维护者永远无法保证用户侧的真实体验。
|
||
- 每一次部署,都应该在真实环境中被验证。
|
||
|
||
**所以:**
|
||
|
||
部署脚本就是发布流水线。开发过程中使用的更新链路,就是最终用户使用的更新链路。
|
||
|
||
没有特权通道,没有隐藏开关。你用的,就是我用的。
|
||
|
||
---
|
||
|
||
## 为什么没有 Patch 版本?
|
||
|
||
版本号格式:`2.5-LTS-260804-203825`
|
||
|
||
详见:[更新策略](./update-strategy.md)
|
||
|
||
---
|
||
|
||
## 为什么支持 ARMHF?
|
||
|
||
详见:[边缘节点部署](./edge-node.md)
|
||
|
||
---
|
||
|
||
## 为什么采用 Preview / LTS 双线版本?
|
||
|
||
详见:[更新策略](./update-strategy.md)
|
||
|
||
---
|
||
|
||
## 为什么“存储换内存”?
|
||
|
||
在边缘设备上,存储和内存的成本结构完全颠倒:
|
||
|
||
| | 服务器 | 边缘设备 |
|
||
|---|---|---|
|
||
| 存储 | 昂贵(NVMe SSD) | 便宜(SD 卡 / eMMC) |
|
||
| 内存 | 便宜(可扩展) | 昂贵(不可扩展,BGA 焊接) |
|
||
|
||
**结论:**
|
||
|
||
镜像大几十 MB,可以接受。内存多占 10MB,不能接受。
|
||
|
||
牺牲存储空间,换来 50MB 以内的内存占用——这笔账在边缘设备上怎么算都不亏。
|
||
|
||
---
|
||
|
||
## 为什么用 SQLite,不用 PostgreSQL / MySQL?
|
||
|
||
- 边缘设备跑不动 PostgreSQL
|
||
- 不需要网络连接
|
||
- 单文件备份,复制即迁移
|
||
- 零配置,零维护
|
||
|
||
符合“降低维护成本”的总体目标。
|
||
|
||
---
|
||
|
||
## 为什么使用 Gin 和 Vue,而不是更轻的框架?
|
||
|
||
这是一个有意识的选择。
|
||
|
||
frpc-console 的 Web 部分需要提供完整的图形化操作界面,不是一个简单的 API 服务。使用成熟的框架,换取开发效率和稳定性。
|
||
|
||
**但要注意:**
|
||
|
||
框架的选择不影响运行时资源占用。前端资源在首次加载后缓存,后端 Gin 在 idle 状态下几乎没有额外开销。
|
||
|
||
---
|
||
|
||
## 为什么默认不写日志?
|
||
|
||
边缘设备存储有限(SD 卡 / eMMC)。
|
||
|
||
默认不写日志,避免存储被写满导致设备不可用。
|
||
|
||
用户需要时,可以显式开启日志功能。
|
||
|
||
---
|
||
|
||
## 为什么 openSUSE 在部署脚本中排第一?
|
||
|
||
详见:[工程设计哲学](./engineering-philosophy.md) 中的“用户不是测试员”和“Real World First”原则。
|
||
|
||
---
|
||
|
||
## 为什么 Docker 和 Binary 都支持?
|
||
|
||
因为使用场景不同:
|
||
|
||
| 场景 | 推荐方式 |
|
||
|---|---|
|
||
| 现代服务器(有 Docker) | Docker |
|
||
| 边缘设备(无 Docker) | Binary |
|
||
| 开发者测试 | Docker |
|
||
| 开发测试(无 Docker)| Binary |
|
||
| 生产环境(有 Docker) | Docker |
|
||
| 生产环境(无 Docker) | Binary |
|
||
|
||
**核心原则:** 无论运行在哪里,体验应该保持一致。
|
||
|
||
---
|
||
|
||
## 为什么叫“阴阳模式”?
|
||
|
||
详见:[工程设计哲学](./engineering-philosophy.md) 中的“阴阳模式”章节。
|
||
|
||
---
|
||
|
||
## 这些决策的共同点
|
||
|
||
所有设计决策,都指向同一个问题:
|
||
|
||
**一个长期运行的基础设施工具,应该是什么样?**
|
||
|
||
答案不是“功能最多”,不是“界面最美”,而是:
|
||
|
||
**降低长期维护的成本。**
|
||
|
||
每一个“为什么”的答案,最终都落在这句话上。
|
||
|
||
---
|
||
|
||
*这份文档会持续更新。每一次新的设计决策,都会被记录在这里。* |