153 lines
5.8 KiB
Markdown
153 lines
5.8 KiB
Markdown
# Project Bootstrap(技术计划)
|
||
|
||
## 1. 目标与约束(来自 spec)
|
||
|
||
- 目标:完成项目初始化可落地的工程与基础设施约定(client/server + dev/prod 隔离 + MySQL/Redis 命名与访问边界)。
|
||
- 关键选择:
|
||
- 后端依赖:`requirements.txt` + `pip`
|
||
- 定时/异步:Celery + Redis
|
||
- 环境:仅 dev / prod
|
||
- Redis 隔离:ACL + key 前缀(`dev:*` / `pro:*`)
|
||
- 部署:**不在本需求中提供 Docker 起 MySQL/Redis**(MySQL/Redis 已部署),后端通过环境变量连接
|
||
- 数据库迁移:Alembic
|
||
- Redis 生产环境:**maxmemory=256MB 硬限制**
|
||
|
||
## 2. 总体方案
|
||
|
||
### 2.1 MySQL(schema 隔离)
|
||
|
||
- prod schema:`mindfulness`
|
||
- dev schema:`mindfulness_dev`
|
||
- 字符集:`utf8mb4`
|
||
- 连接方式:后端通过 `DATABASE_URL`(SQLAlchemy Async)连接到对应 schema
|
||
|
||
### 2.2 Redis(ACL + 前缀隔离 + 内存限制)
|
||
|
||
- 单 Redis 实例(同机同容器可行)。
|
||
- 通过 **ACL 用户**限制不同环境只能访问各自前缀:
|
||
- dev 用户:只能访问 `dev:*`
|
||
- prod 用户:只能访问 `pro:*`
|
||
- 应用侧硬约束:所有 Redis key 必须带环境前缀(`dev:` / `pro:`)。
|
||
- 生产 maxmemory:`256mb`,并采用“少用 Redis、短 TTL、避免任务积压”的策略。
|
||
|
||
> 重要:Celery broker 以“可靠投递”为优先,计划中默认 **不启用** Celery result backend(或启用时必须设置 TTL)。
|
||
|
||
### 2.3 运行方式(不限定部署形态)
|
||
|
||
本需求只要求:
|
||
|
||
- MySQL 与 Redis **已可访问**
|
||
- 后端通过 `.env.dev/.env.prod`(或等价环境变量注入方式)获取连接信息
|
||
- API/Celery/Beat 以任意进程管理方式运行(Docker/systemd/进程托管均可),但需满足验收项
|
||
|
||
## 3. 目录与文件落地清单
|
||
|
||
> 本计划只定义“应该创建/调整什么”,具体文件内容在 tasks 阶段逐项实现。
|
||
|
||
### 3.1 后端依赖与启动入口(server)
|
||
|
||
- `server/requirements.txt`
|
||
- `server/app/main.py`(FastAPI 入口)
|
||
- `server/app/core/config.py`(pydantic-settings,按 `APP_ENV` 加载 `.env.dev/.env.prod`)
|
||
- `server/app/worker.py`(Celery app 入口)
|
||
- `server/alembic.ini` + `server/alembic/`(迁移脚手架)
|
||
- `server/.env.example`(字段结构,不含真实值)
|
||
|
||
### 3.2 基础设施(infra)
|
||
|
||
本需求不强制创建 `infra/`(因为 MySQL/Redis 已部署)。
|
||
|
||
可选新增(仅用于“文档化配置/备份参考”,不要求参与部署):
|
||
|
||
- `infra/redis/users.acl`(ACL 用户定义备份)
|
||
- `infra/redis/redis.prod.conf`(prod 配置备份,包含 maxmemory=256mb)
|
||
- `infra/mysql/init/00-create-schemas.sql`(创建 `mindfulness_dev/mindfulness` 的 SQL 备份)
|
||
|
||
## 4. Redis ACL 与 maxmemory 的落地方案
|
||
|
||
### 4.1 ACL 文件(`infra/redis/users.acl`)
|
||
|
||
> 若 Redis 已在服务器配置完成,本节用于“约定与验收”。
|
||
|
||
- 定义 `dev_user`、`pro_user` 两个账号
|
||
- 分别限制 key pattern:
|
||
- dev:`~dev:*`
|
||
- prod:`~pro:*`
|
||
- 建议禁用默认用户,避免未授权访问(推荐):`user default off`
|
||
|
||
### 4.2 Redis 配置(`infra/redis/redis.prod.conf`)
|
||
|
||
> 若 Redis 已在服务器配置完成,本节用于“约定与验收”。
|
||
|
||
- `maxmemory 256mb`
|
||
- `maxmemory-policy noeviction`(队列场景优先“不丢任务”,宁可让写入失败报警)
|
||
- 开启 ACL(例如 `aclfile .../users.acl`)
|
||
|
||
### 4.3 应用侧约束(在代码实现时落地)
|
||
|
||
为确保 ACL 真的起作用,需要做到:
|
||
|
||
- **所有业务 key 带前缀**:例如 `dev:cache:...` / `pro:cache:...`
|
||
- **Celery 队列名带前缀**:例如 `dev:push` / `pro:push`
|
||
- **禁用或限制 result backend**:默认不启用;如启用必须设置短 TTL(例如 1 小时/1 天)
|
||
- **任务参数保持小**:只传 id,不传长文本/大 payload,避免队列膨胀导致 Redis 触顶
|
||
|
||
## 5. 环境变量与配置约定
|
||
|
||
### 5.1 后端 `.env.dev/.env.prod`(字段示例)
|
||
|
||
- `APP_ENV=dev|prod`
|
||
- `DATABASE_URL=.../mindfulness_dev`(dev)或 `.../mindfulness`(prod)
|
||
- `REDIS_URL=redis://<user>:<pass>@redis:6379/0`
|
||
- `CELERY_BROKER_URL=redis://<user>:<pass>@redis:6379/0`
|
||
- `CELERY_RESULT_BACKEND`:默认不配置(或仅在 dev 开启)
|
||
|
||
### 5.2 密钥管理
|
||
|
||
- `.env.dev/.env.prod` 不进仓库
|
||
- 提供 `.env.example` 仅展示字段结构
|
||
|
||
## 6. 实施步骤(建议顺序)
|
||
|
||
### 阶段 A:验证现有 MySQL/Redis 与隔离策略
|
||
|
||
- Redis:ACL 生效验证(dev 用户无法访问 `pro:*`,prod 用户无法访问 `dev:*`)
|
||
- Redis:prod 配置验证(`maxmemory=256mb` 生效)
|
||
- MySQL:确认 `mindfulness_dev` 与 `mindfulness` 两个 schema 已创建(若未创建则创建)
|
||
|
||
### 阶段 B:后端最小可运行骨架
|
||
|
||
- `requirements.txt` 固化依赖
|
||
- FastAPI 最小健康检查接口(如 `/healthz`)
|
||
- SQLAlchemy 连接与基础会话
|
||
- Alembic 初始化与一次空迁移验证
|
||
|
||
### 阶段 C:Celery 最小闭环
|
||
|
||
- Celery app 初始化,broker 指向 Redis(按环境选择 dev_user/pro_user)
|
||
- 1 个示例任务(例如打印/写库)验证 worker 可消费
|
||
- 如需要定时:beat 定时触发任务验证
|
||
|
||
## 7. 验收与自检清单(plan 阶段定义)
|
||
|
||
- **环境隔离**
|
||
- dev 连接 `mindfulness_dev`,prod 连接 `mindfulness`
|
||
- dev 的 Redis 凭证无法读写 `pro:*`,反之亦然
|
||
- **资源约束**
|
||
- prod Redis `maxmemory=256mb` 生效
|
||
- 不启用(或短 TTL)result backend,避免长期堆积
|
||
- **可运行性**
|
||
- FastAPI 能启动并提供基础接口
|
||
- Celery worker 能消费任务,beat(如启用)能触发定时任务
|
||
|
||
## 8. 风险与应对
|
||
|
||
- Redis 256MB 触顶风险:
|
||
- 控制队列积压(worker 数量/并发)
|
||
- 禁用或缩短结果存储 TTL
|
||
- 任务 payload 只传 id
|
||
- 多环境同机误用风险:
|
||
- 强制不同 ACL 用户 + 前缀
|
||
- Celery 队列名带前缀,避免互相消费
|
||
|