签入版本

This commit is contained in:
2026-09-12 17:39:13 +08:00
parent 25c8b039ac
commit 3233d221b0
871 changed files with 103088 additions and 10561 deletions
+419
View File
@@ -0,0 +1,419 @@
# 系统架构说明
本文档详细说明 DjangoAdmin FastAPI + EleVue 版本的整体架构设计、分层模式、核心模块以及关键设计决策。
## 📐 整体架构
### 前后端分离架构
```
┌─────────────────────────────────────────────────────────────┐
│ 前端 (Vue 3) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Vue 3 │ │ Element │ │ Pinia │ │ Vue │ │
│ │ + TS │ │ Plus │ │ 状态管理 │ │ Router │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
│ ↕ Axios HTTP Client (Bearer Token) │
└─────────────────────────────────────────────────────────────┘
↕ JSON / JWT
┌─────────────────────────────────────────────────────────────┐
│ 后端 (FastAPI) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 中间件链 │ │
│ │ CORS → Redis注入 → 限流 → DB会话 → 操作日志 → 日志 │ │
│ └─────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ API 路由层 │ │
│ │ /api/v1/auth/* (免认证) /api/v1/* (login_required) │ │
│ │ @permission_required @check_demo │ │
│ └─────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 业务模块层 │ │
│ │ Service → Repository → Model │ │
│ └─────────────────────────────────────────────────────┘ │
│ ↕ ↕ │
│ ┌──────────┐ ┌──────────┐ │
│ │ MySQL / │ │ Redis │ │
│ │ PG / │ │ 缓存 │ │
│ │ MSSQL / │ │ 会话 │ │
│ │ Oracle │ │ 黑名单 │ │
│ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────────────────────┘
```
## 🔄 请求处理流程
### 完整请求生命周期
```
1. 客户端发起 HTTP 请求
↓
2. CORS 中间件(src/middleware/cors.py)
- 处理跨域预检请求
↓
3. Redis 注入中间件(src/core/redis_client.py: redis_middleware)
- 将异步 Redis 客户端注入 contextvars
↓
4. 限流中间件(src/middleware/rate_limit.py)
- 基于 Redis 滑动窗口的 per-IP 限流
- 超限返回 {code: 1} 标准响应
↓
5. DB 会话中间件(src/middleware/db_session.py)
- 创建请求级数据库会话
- 请求结束后自动 commit/rollback
↓
6. 操作日志中间件(src/middleware/operation_log.py)
- 记录写操作(POST/PUT/DELETE)的行为日志
↓
7. 路由匹配
- auth 路由(/api/v1/auth/*):免认证
- v1 路由(/api/v1/*):login_required 依赖校验 JWT
↓
8. 权限装饰器 @permission_required
- 校验当前用户是否有该接口的权限
- 用户 ID 1(admin)自动跳过权限检查
↓
9. 演示模式装饰器 @check_demo
- 演示环境下拦截写操作
↓
10. 端点处理函数
- 参数由 Pydantic 自动校验
- 调用 Service 层业务逻辑
- 返回 R.ok() / R.failed() 统一响应
↓
11. 异常处理
- RequestValidationError → {code: 1, msg: "field: message"}
- BusinessException → {code: 1, msg: "业务错误"}
- AuthorizationException → {code: 401, msg: "认证失败"}
```
## 📦 分层模块模式
### 四层架构
每个业务模块遵循统一的四层架构设计:
```
src/modules/{group}/{name}/
├── models.py # 数据模型层 — SQLAlchemy ORM 模型定义
├── schemas.py # 数据校验层 — Pydantic 请求/响应模型
├── repository.py # 数据访问层 — 通用 CRUD 与自定义查询
└── service.py # 业务逻辑层 — 事务管理、缓存、业务规则
```
#### Model 层(数据模型)
```python
# src/modules/system/level/models.py
from core.base_model import base_model
from core.base_db import base_db
from core.config.database import DB_PREFIX
class SysLevel(base_model, base_db):
"""职级表"""
__tablename__ = DB_PREFIX + "level"
name = Column(String(100), nullable=False, comment="职级名称")
code = Column(String(50), nullable=False, comment="职级编码")
sort = Column(Integer, default=0, comment="排序")
status = Column(Integer, default=1, comment="状态 1=启用 0=禁用")
remark = Column(String(500), comment="备注")
```
- 继承 `base_model`:提供 `id`, `create_user`, `create_time`, `update_user`, `update_time`, `is_delete`
- 继承 `base_db`:提供 `save()`, `delete()` 实例方法
- 表名使用 `DB_PREFIX` 前缀,支持多项目共库
#### Schema 层(数据校验)
```python
# src/modules/system/level/schemas.py
from pydantic import BaseModel, Field, field_validator
class LevelForm(BaseModel):
"""职级表单"""
id: Optional[int] = Field(None, description="ID")
name: str = Field(..., min_length=1, max_length=100, description="职级名称")
code: str = Field(..., min_length=1, max_length=50, description="职级编码")
sort: int = Field(0, ge=0, description="排序")
status: int = Field(1, description="状态")
remark: Optional[str] = Field(None, max_length=500, description="备注")
@field_validator('name')
@classmethod
def validate_name(cls, v):
if not v.strip():
raise ValueError("职级名称不能为空")
return v.strip()
```
- 继承 Pydantic `BaseModel`
- 使用 `Field(...)` 定义约束(`min_length`, `max_length`, `ge`, `le`)
- 使用 `@field_validator` 自定义校验逻辑
#### Repository 层(数据访问)
```python
# src/modules/system/level/repository.py
from core.base_repository import BaseRepository
from .models import SysLevel
class LevelRepository(BaseRepository[SysLevel]):
model = SysLevel
level_repo = LevelRepository()
```
- 继承 `BaseRepository[Model]`,自动获得通用 CRUD 方法
- 模块级单例 `{name}_repo`,全局复用
- 基类提供:`get_by_id`, `get_one`, `get_all`, `exists`, `exists_by_field`, `count`, `filter`, `filter_by`, `create`, `update`, `paginate`, `batch_delete`
- 等值查询自动软删过滤且跳过 None 值
#### Service 层(业务逻辑)
```python
# src/modules/system/level/service.py
from core.base_service import BaseService
from .models import SysLevel
from .repository import level_repo
class LevelService(BaseService[SysLevel]):
repo = level_repo
model = SysLevel
page_like_fields = ["name", "code"]
page_eq_fields = ["status"]
page_order_by = ["sort", "id"]
unique_fields = [("name", "职级名称"), ("code", "职级编码")]
level_service = LevelService()
```
- 继承 `BaseService[Model]`,声明差异即可获得完整 CRUD
- 可覆盖钩子:`_apply_page_filters`, `_serialize`, `_build_create_fields`, `_build_update_fields`
- 删除统一使用 `BaseService.batch_delete_with_r(repo, ids)` 静态方法
### HTTP 层(API 端点)
```python
# src/api/v1/endpoints/level.py
from fastapi import APIRouter, Request
from core.access_decorators import permission_required, check_demo
router = APIRouter()
@router.get('/list')
@permission_required("sys:level:list")
async def list(request: Request):
"""职级列表"""
return await level_service.page_list(request)
@router.post('/add')
@permission_required("sys:level:add")
@check_demo
async def add(request: Request, data: LevelForm):
"""新增职级"""
return await level_service.add(request, data)
```
- 路由定义、权限装饰器、请求/响应处理
- 无业务逻辑,纯委托给 Service 层
## 🔐 认证与授权
### JWT 认证流程
```
1. 登录(/api/v1/auth/login)
- 验证用户名 + 密码(bcrypt)
- 验证图形验证码
- 生成 JWT Token(HS256 签名)
- 返回 {access_token, token_type}
2. 请求认证(login_required 依赖)
- 从 Authorization: Bearer <token> 提取 Token
- 解析 JWT,验证签名与过期时间
- 检查 Token 是否在 Redis 黑名单中
- 设置 request.state.user_id / username / realname
3. Token 刷新(/api/v1/auth/refresh)
- 使用当前 Token 获取新 Token
- 旧 Token 加入 Redis 黑名单
4. 登出(/api/v1/auth/logout)
- 当前 Token 加入 Redis 黑名单
```
### RBAC 权限模型
```
用户(User) ←→ 角色(Role) ←→ 菜单(Menu)
│ │ │
└─ user_role └─ role_menu └─ 权限标识
(sys:level:list)
```
- **用户-角色**:多对多关系(`sys_user_role` 中间表)
- **角色-菜单**:多对多关系(`sys_role_menu` 中间表)
- **菜单**:存储权限标识(如 `sys:level:list`),支持目录/菜单/按钮三种类型
- **权限检查**:`@permission_required("sys:level:list")` 装饰器在端点执行前校验
- **管理员豁免**:用户 ID 1(admin)自动跳过所有权限检查
## 🗄️ 数据库设计
### 多数据库支持
框架通过 `DB_DRIVER` 环境变量切换数据库方言:
```python
# src/core/config/database.py
DB_DRIVER = os.getenv("DB_DRIVER", "mysql")
# 驱动注册表
DRIVERS = {
"mysql": "pymysql",
"postgresql": "psycopg",
"mssql": "pymssql",
"oracle": "oracledb",
"sqlite": "sqlite3",
}
```
- SQLAlchemy 引擎根据驱动自动选择方言
- Model 层使用 SQLAlchemy 声明式映射,与具体数据库解耦
- Alembic 迁移脚本自动适配方言 DDL
### 软删除机制
所有业务表使用 `is_delete` 字段实现软删除:
- `is_delete = 0`:正常记录
- `is_delete = 1`:已删除记录
Repository 基类的等值查询方法(`get_one`, `get_all`, `count`, `filter_by`, `exists_by_field`)自动过滤已删除记录。
### 跨库数据迁移
`scripts/migrate_db.py` 支持从 MySQL 迁移数据到任意目标数据库:
1. 拓扑排序确定表依赖关系
2. 分块 `SELECT * ... ORDER BY id` + `executemany` 显式带 ID 插入
3. 自增序列重置(PG `setval` / MSSQL `DBCC CHECKIDENT`)
4. 逐表 `COUNT(*)` 校验数据一致性
## ⚡ 同步/异步约定
| 场景 | 方式 | 说明 |
|---|---|---|
| 纯 DB CRUD | 同步 `def` | FastAPI 自动在线程池执行,不阻塞事件循环 |
| 需要 `await`(Redis/异步IO) | `async def` + `asyncio.to_thread` | 同步操作用 `to_thread` 包裹 |
| 批量删除端点 | `async def` | 需 `await parse_batch_ids(request)` 异步读请求体 |
**禁止**在 `async def` 端点或 Service 内直接调用同步 DB 查询(会阻塞事件循环)。
## 📁 目录结构
```
DjangoAdmin_FastAPI_EleVue/
├── src/ # 后端源码
│ ├── main.py # 应用入口
│ ├── core/ # 核心基础设施
│ │ ├── app.py # 应用工厂(create_app)
│ │ ├── config/ # 配置模块(app/database/redis/auth/captcha/email/sms)
│ │ ├── database.py # 引擎/会话/上下文
│ │ ├── redis_client.py # Redis 异步客户端
│ │ ├── jwt.py # JWT 认证
│ │ ├── password.py # 密码加密
│ │ ├── response.py # 统一响应封装
│ │ ├── exceptions.py # 异常定义
│ │ ├── security.py # 安全工具
│ │ ├── access_decorators.py # 权限/演示模式装饰器
│ │ ├── logger.py # 日志配置
│ │ ├── base_model.py # ORM 基础模型
│ │ ├── base_db.py # 数据库操作基类
│ │ ├── base_repository.py # Repository 基类
│ │ └── base_service.py # Service 基类
│ ├── api/ # API 路由层
│ │ ├── __init__.py # 路由注册(register_router)
│ │ ├── deps.py # login_required 依赖
│ │ └── v1/
│ │ ├── router.py # 路由汇总
│ │ └── endpoints/ # 各模块端点定义
│ ├── modules/ # 业务模块层
│ │ ├── auth/ # 认证模块
│ │ ├── system/ # 系统管理(user/role/menu/dept/position/level)
│ │ ├── dictionary/ # 字典管理
│ │ ├── configuration/ # 配置管理
│ │ ├── article/ # 文章管理
│ │ ├── notice/ # 通知公告
│ │ ├── job/ # 定时任务
│ │ └── ... # 其他业务模块
│ ├── middleware/ # HTTP 中间件
│ │ ├── cors.py # 跨域处理
│ │ ├── rate_limit.py # 限流中间件
│ │ ├── db_session.py # DB 会话管理
│ │ ├── operation_log.py # 操作日志
│ │ └── logger.py # 请求日志
│ ├── constants/ # 常量与枚举
│ └── utils/ # 工具函数
├── ui/ # 前端源码(Vue 3 + TypeScript)
├── scripts/ # 运维脚本
│ ├── init_db.py # 数据库初始化
│ ├── seed_dict.py # 字典数据种子
│ ├── migrate_db.py # 跨库数据迁移
│ └── demo_job_loop.py # 定时任务演示
├── tests/ # 测试代码
│ ├── contract/ # 契约快照测试
│ ├── unit/ # 单元测试
│ └── integration/ # 集成测试
├── migrations/ # Alembic 迁移脚本
├── document/ # 项目文档
├── .env # 环境变量配置
├── docker-compose.yml # Docker 编排
├── Dockerfile # Docker 镜像构建
├── Makefile # 常用命令
├── requirements.txt # Python 依赖
├── alembic.ini # Alembic 配置
└── pytest.ini # 测试配置
```
## 🔧 核心设计决策
### 1. 为什么选择 Repository + Service 双层?
- **Repository** 封装数据访问细节,提供通用 CRUD,隔离 ORM 实现
- **Service** 封装业务逻辑,管理事务、缓存、权限等横切关注点
- 两层分离使得业务逻辑可独立测试,数据访问可独立优化
### 2. 为什么使用 contextvars 管理 DB 会话?
- FastAPI 的依赖注入不适合跨层级传递数据库会话
- `contextvars` 提供协程安全的请求级上下文
- 中间件创建会话,`get_db_session()` 在任意层级获取当前会话
- 请求结束自动 commit/rollback,无需手动管理
### 3. 为什么使用软删除?
- 保留历史数据,支持数据审计和恢复
- 避免外键级联删除导致数据丢失
- Repository 基类自动过滤,业务层无需关心
### 4. 为什么 BaseRepository 等值查询跳过 None?
- 避免 `filter_by(name=None)` 生成 `WHERE name = NULL`(SQL 中应为 `IS NULL`)
- 简化 Service 层的条件构建,无需逐一判断 None
- 提供 `filter()` 原始出口供复杂查询使用
## 📚 相关文档
- [部署指南](DEPLOYMENT.md) — Docker / 手动 / 生产环境部署
- [数据库迁移](../document/数据库迁移_runbook.md) — 跨库迁移操作手册
- [开发文档](http://docs.fastapi.elevue.djangoadmin.cn) — 在线开发文档
+476
View File
@@ -0,0 +1,476 @@
# 部署指南
本文档介绍 DjangoAdmin FastAPI + EleVue 版本的多种部署方式,包括本地开发、Docker 容器化部署以及生产环境部署。
## 📋 环境要求
### 后端
| 依赖 | 最低版本 | 说明 |
|---|---|---|
| Python | 3.10+ | 推荐 3.11 或 3.12 |
| MySQL | 5.7+ | 默认数据库,推荐 8.0+ |
| PostgreSQL | 12+ | 可选,设置 `DB_DRIVER=postgresql` |
| SQL Server | 2017+ | 可选,设置 `DB_DRIVER=mssql` |
| Oracle | 19c+ | 可选,设置 `DB_DRIVER=oracle` |
| Redis | 6.0+ | 必需,用于缓存/会话/限流 |
### 前端
| 依赖 | 最低版本 | 说明 |
|---|---|---|
| Node.js | 18+ | 推荐 20 LTS |
| npm | 8+ | 或使用 pnpm / yarn |
## 🚀 方式一:本地开发环境
### 1. 克隆项目
```bash
git clone https://gitee.com/djangoadmin/DjangoAdmin_Fastapi_EleVue.git
cd DjangoAdmin_Fastapi_EleVue
```
### 2. 配置环境变量
```bash
cp .env.example .env
```
编辑 `.env` 文件,配置以下关键变量:
```env
# ============ 数据库配置 ============
DB_DRIVER=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_USER=root
DB_PASSWORD=your_password
DB_NAME=djangoadmin
DB_PREFIX=fastapi_
# ============ Redis 配置 ============
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_PASSWORD=
REDIS_DB=0
# ============ JWT 配置 ============
JWT_SALT=your-secret-key-change-in-production
JWT_EXPIRE_MINUTES=120
# ============ 应用配置 ============
APP_HOST=127.0.0.1
APP_PORT=8031
FASTAPI_DEMO=False
```
### 3. 安装依赖
```bash
# 运行 + 开发依赖
pip install -r requirements.txt -r requirements-dev.txt
# 或使用 Makefile
make install
```
### 4. 初始化数据库
```bash
# 自动建库 + 导入 SQL + 创建表 + Alembic stamp
python scripts/init_db.py
# 或使用 Makefile
make db-init
```
### 5. 初始化字典数据(可选)
```bash
python scripts/seed_dict.py
make seed-dict
```
### 6. 启动后端服务
```bash
python src/main.py
# 或使用 Makefile
make dev
# 默认监听 http://127.0.0.1:8031
# API 文档:http://127.0.0.1:8031/docs
```
### 7. 启动前端服务
```bash
cd ui
npm install
npm run dev
# 默认监听 http://localhost:3000
```
## 🐳 方式二:Docker Compose 部署
### 1. 配置环境变量
```bash
cp .env.example .env
# 编辑 .env,将 DB_HOST 和 REDIS_HOST 改为容器名或宿主机 IP
```
> ⚠️ Docker `host` 网络模式下,`DB_HOST` 和 `REDIS_HOST` 可直接使用 `127.0.0.1`。
> 若使用 `bridge` 网络模式,需改为 `host.docker.internal` 或宿主机实际 IP。
### 2. 构建并启动
```bash
docker-compose up --build -d
```
### 3. 查看日志
```bash
docker-compose logs -f fastapi_elevue
```
### 4. 停止服务
```bash
docker-compose down
```
### Docker Compose 配置说明
```yaml
services:
fastapi_elevue:
image: fastapi_elevue
container_name: fastapi_elevue
build:
context: ./
dockerfile: Dockerfile
restart: always
network_mode: host # host 模式,直接连通宿主机网络
ports:
- 8031:8031 # bridge 模式下的端口映射
volumes:
- ./uploads:/data/apps/uploads # 上传文件持久化
env_file:
- .env # 注入环境变量
command: python src/main.py
logging:
driver: "json-file"
options:
max-size: "500m" # 单个日志文件最大 500MB
max-file: "10" # 最多保留 10 个日志文件
```
## 🏭 方式三:生产环境部署
### 使用 Gunicorn + Uvicorn Worker
生产环境推荐使用 Gunicorn 管理 Uvicorn Worker:
```bash
pip install gunicorn
gunicorn main:app \
--app-dir src \
--workers 4 \
--worker-class uvicorn.workers.UvicornWorker \
--bind 0.0.0.0:8031 \
--timeout 120 \
--access-logfile - \
--error-logfile -
```
**Worker 数量建议**:
- CPU 密集型:`workers = CPU 核心数 + 1`
- IO 密集型:`workers = CPU 核心数 * 2 + 1`
- 一般推荐:4 ~ 8 个 Worker
### 使用 Supervisor 进程管理
项目已提供 `deploy/supervisor.conf` 配置文件:
```ini
[program:fastapi_elevue]
command=/path/to/venv/bin/gunicorn main:app
--app-dir /path/to/project/src
--workers 4
--worker-class uvicorn.workers.UvicornWorker
--bind 0.0.0.0:8031
directory=/path/to/project
user=www
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/var/log/fastapi_elevue/stdout.log
stderr_logfile=/var/log/fastapi_elevue/stderr.log
```
```bash
# 启动
sudo supervisorctl start fastapi_elevue
# 查看状态
sudo supervisorctl status fastapi_elevue
# 重启
sudo supervisorctl restart fastapi_elevue
```
### Nginx 反向代理
```nginx
server {
listen 80;
server_name your-domain.com;
# 前端静态文件
location / {
root /path/to/ui/dist;
try_files $uri $uri/ /index.html;
}
# 后端 API 代理
location /api/ {
proxy_pass http://127.0.0.1:8031;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 120s;
}
# 上传文件访问
location /uploads/ {
alias /path/to/project/uploads/;
expires 7d;
}
}
```
### 前端构建
```bash
cd ui
# 安装依赖
npm install
# 生产构建
npm run build
# 构建产物在 ui/dist/ 目录
```
## 🗄️ 数据库配置
### MySQL(默认)
```env
DB_DRIVER=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_USER=root
DB_PASSWORD=your_password
DB_NAME=djangoadmin
```
### PostgreSQL
```env
DB_DRIVER=postgresql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=your_password
DB_NAME=djangoadmin
```
安装驱动:
```bash
pip install "psycopg[binary]"
```
### SQL Server
```env
DB_DRIVER=mssql
DB_HOST=127.0.0.1
DB_PORT=1433
DB_USER=sa
DB_PASSWORD=your_password
DB_NAME=djangoadmin
```
安装驱动:
```bash
pip install pymssql
```
### Oracle
```env
DB_DRIVER=oracle
DB_HOST=127.0.0.1
DB_PORT=1521
DB_USER=system
DB_PASSWORD=your_password
DB_NAME=ORCL
```
安装驱动:
```bash
pip install oracledb
```
### SQLite
```env
DB_DRIVER=sqlite
DB_NAME=djangoadmin.db
```
> 💡 SQLite 无需额外驱动,Python 内置支持。适合开发/测试环境。
## 🔄 跨库数据迁移
将现有 MySQL 数据迁移到其他数据库:
```bash
# 1. 干跑 — 只连接源库,逐表数行数,打印迁移计划
make db-migrate-dry-run ARGS="--src-driver=mysql --src-host=127.0.0.1 --src-db=djangoadmin --src-user=root --src-password=xxx --dst-driver=postgresql --dst-host=127.0.0.1 --dst-db=djangoadmin --dst-user=postgres --dst-password=xxx"
# 2. 正式迁移
make db-migrate ARGS="--src-driver=mysql --src-host=127.0.0.1 --src-db=djangoadmin --src-user=root --src-password=xxx --dst-driver=postgresql --dst-host=127.0.0.1 --dst-db=djangoadmin --dst-user=postgres --dst-password=xxx"
# 3. 幂等重跑(加 --drop-target-first)
make db-migrate ARGS="... --drop-target-first"
```
详细操作手册参阅 [数据库迁移 Runbook](../document/数据库迁移_runbook.md)。
## 🧪 测试
```bash
# 运行全部测试(默认跳过集成测试)
pytest
# 单元测试
pytest tests/unit
# 契约快照测试(守护路由/权限/表名)
pytest tests/contract -m contract
# 集成测试(需真实 MySQL/Redis)
pytest tests/integration -m integration
# 查看覆盖率
pytest --cov=src --cov-report=html
```
## 🔍 健康检查
### API 健康检查端点
```bash
# 检查后端服务是否正常
curl http://127.0.0.1:8031/api/v1/auth/captcha
# 检查 Redis 连接
redis-cli ping
# 检查 MySQL 连接
mysql -u root -p -e "SELECT 1"
```
### 日志查看
```bash
# 应用日志
tail -f logs/app.log
# 错误日志
tail -f logs/error.log
# Docker 日志
docker-compose logs -f --tail=100
```
## ⚙️ 性能调优
### 数据库连接池
在 `.env` 中配置:
```env
# 连接池大小
DB_POOL_SIZE=10
# 最大溢出连接数
DB_MAX_OVERFLOW=20
# 连接超时(秒)
DB_POOL_TIMEOUT=30
# 连接回收时间(秒)
DB_POOL_RECYCLE=1800
```
### Redis 连接池
```env
REDIS_MAX_CONNECTIONS=20
```
### Uvicorn Worker
根据服务器配置调整 Worker 数量:
```bash
# 4 核 8G 内存服务器
gunicorn main:app --app-dir src --workers 4 --worker-class uvicorn.workers.UvicornWorker
# 8 核 16G 内存服务器
gunicorn main:app --app-dir src --workers 8 --worker-class uvicorn.workers.UvicornWorker
```
## ❓ 常见问题
### Q: 数据库连接失败?
1. 检查数据库服务是否启动
2. 检查 `.env` 中的连接参数是否正确
3. 检查防火墙是否开放对应端口
4. 检查数据库用户是否有远程访问权限
### Q: Redis 连接失败?
1. 检查 Redis 服务是否启动:`redis-cli ping`
2. 检查 `.env` 中的 Redis 配置
3. 如设置了密码,确认 `REDIS_PASSWORD` 正确
### Q: 前端请求 404?
1. 确认后端服务已启动
2. 检查前端代理配置(`vite.config.ts` 中的 `proxy`)
3. 确认 API 前缀为 `/api/v1`
### Q: Token 过期后无法刷新?
1. 检查 Redis 是否正常运行(Token 黑名单存储在 Redis 中)
2. 确认 `JWT_EXPIRE_MINUTES` 配置合理
3. 前端应在收到 401 时自动调用刷新接口