Appearance
架构
Memos 总体系统结构和主要组成部分
总体上来看,Memos 是一个轻量级的 web 应用程序,并包含用户界面、后端接口、服务层、数据库后端和可选的脱离于数据库的附件存储。
技术栈
| 技术层 | 技术 |
|---|---|
| 后端语言 | Go 1.25+ |
| HTTP 路由 | Echo v5 |
| API 协议 | gRPC + Connect RPC(双协议) |
| 模式 | Protocol Buffers v2 |
| 数据库 | SQLite(默认)、MySQL、PostgreSQL |
| 前端框架 | React 18 + TypeScript |
| 前端构建工具 | Vite 7 |
| 状态管理 | React Query v5 + React Context |
| 前端 API 客户端 | Connect RPC |
| 前端样式库 | Tailwind CSS v4 |
主要层级
- 前端界面负责笔记的编写、浏览、管理
- 接口和服务层负责认证、笔记设置、实例管理
- 数据库层负责保存内容和元数据
- 附件存放在文件系统(可选)或对象存储中
双协议 API
Memos 提供两套 API,它们都基于同一套服务实现:
- Connect RPC 在
/memos.api.v1.*下 — 提供给浏览器前端使用; 支持 HTTP/JSON 方式通信,并提供类型安全的客户端。
- gRPC-Gateway 在
/api/v1/*下 — 为外部工具、CLI 客户端和外部集成提供兼容 REST 风格的 HTTP/JSON 接口。
上述二者的请求都会经过相同的链式拦截器(元数据提取、请求日志、容灾、认证器)。
认证令牌
Memos 中使用了三种令牌:
| 类型 | 声明周期 | 存储方式 | 验证方式 |
|---|---|---|---|
| Access token (JWT) | 15 分钟 | 客户端内存中 | 无状态签名验证 |
| Refresh token (JWT) | 30 天 | 只有 HTTP cookie | 基于数据库,可撤销 |
| 个人访问令牌 (PAT) | 用户自行选择 | 数据库内,SHA-256 哈希串 | 查库 |
个人访问令牌使用 memos_pat_ 前缀,后接 32 位随机字符。数据库中只存储对应的 SHA-256 哈希值。
内存中的缓存数据
存储层为热数据维护了一份内存中的缓存:
| 缓存数据 | 缓存 Key | 过期时间 |
|---|---|---|
| 实例配置 | setting_key | 10 分钟 |
| 用户 | user_id | 10 分钟 |
| 用户配置 | user_id-setting_key | 10 分钟 |
缓存内容会在执行写操作时或是到期后被移除。
架构的重要性
理解架构层次有助于:
- 选择数据库:SQLite、 MySQL 还是 PostgreSQL
- 正确规划备份
- 思考关于存储和代理配置
- 遇到性能问题时,决定从哪开始排查
实际部署时阅读
对于大多数团队而言,架构问题最终都是运维问题:
- 数据存放在哪
- TLS 在哪一层终止
- 在备份和恢复期间,附件文件发生了什么
- 多少个实例需要向数据库写数据