242 lines
16 KiB
Markdown
242 lines
16 KiB
Markdown
# 整体架构图
|
||
|
||
本章从全局视角阐述系统的整体技术架构,涵盖前端、后端、数据库及基础设施等核心组成部分,旨在帮助开发者快速建立对系统全貌的清晰认知,为后续的开发和运维工作奠定基础。
|
||
|
||
## 架构总览
|
||
|
||
下图展示了从用户浏览器发起请求到最终返回响应的完整链路:
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────────────┐
|
||
│ Browser (Vue3 + AntDesign Vue) │
|
||
│ Axios HTTP Request / Vite Dev Proxy │
|
||
└──────────────────────────────┬──────────────────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────────────────┐
|
||
│ Nginx (反向代理) │
|
||
│ 静态资源 / SSL 终止 / 负载均衡 / gzip 压缩 │
|
||
└──────────────────────────────┬──────────────────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────────────────┐
|
||
│ FastAPI Application │
|
||
│ ┌───────────────────────────────────────────────────────────────────┐ │
|
||
│ │ Middleware Chain (洋葱模型) │ │
|
||
│ │ ┌─────────┐ ┌─────────┐ ┌──────────┐ ┌─────────┐ ┌───────┐ │ │
|
||
│ │ │ CORS │→│ Redis │→│ RateLimit │→│ DBSession│→│OpLog │ │ │
|
||
│ │ │ 跨域处理 │ │ 上下文 │ │ 滑动窗口 │ │ 会话管理 │ │操作日志│ │ │
|
||
│ │ └─────────┘ └─────────┘ └──────────┘ └─────────┘ └───────┘ │ │
|
||
│ └───────────────────────────────┬───────────────────────────────────┘ │
|
||
│ ▼ │
|
||
│ ┌───────────────────────────────────────────────────────────────────┐ │
|
||
│ │ Router (路由分发) │ │
|
||
│ │ ┌─────────────┐ ┌──────────────┐ ┌──────────────────────────┐ │ │
|
||
│ │ │login_required│→│permission_ │→│ Endpoint (HTTP 层) │ │ │
|
||
│ │ │ JWT 认证 │ │ required │ │ @router.get/post/put/del │ │ │
|
||
│ │ │ │ │ RBAC 鉴权 │ │ Pydantic 参数校验 │ │ │
|
||
│ │ └─────────────┘ └──────────────┘ └────────────┬─────────────┘ │ │
|
||
│ └───────────────────────────────────────────────────┼───────────────┘ │
|
||
│ ▼ │
|
||
│ ┌───────────────────────────────────────────────────────────────────┐ │
|
||
│ │ Service Layer (业务逻辑层) │ │
|
||
│ │ BaseService / 自定义 Service │ │
|
||
│ │ 唯一性校验 · 字段组装 · 序列化 · 文件处理 · 缓存管理 │ │
|
||
│ └───────────────────────────────┬───────────────────────────────────┘ │
|
||
│ ▼ │
|
||
│ ┌───────────────────────────────────────────────────────────────────┐ │
|
||
│ │ Repository Layer (数据访问层) │ │
|
||
│ │ BaseRepository[Model] │ │
|
||
│ │ CRUD · 软删除 · 分页 · 等值查询 · 原始条件查询 │ │
|
||
│ └───────────────────────────────┬───────────────────────────────────┘ │
|
||
│ ▼ │
|
||
│ ┌─────────────────────┐ ┌──────────────────────────────────────────┐ │
|
||
│ │ SQLAlchemy 2.0 │ │ Redis (async) │ │
|
||
│ │ ORM → SQL 生成 │ │ Token 黑名单 · 登录锁 · 限流计数 · 缓存 │ │
|
||
│ └──────────┬──────────┘ └──────────────────────────────────────────┘ │
|
||
└─────────────┼───────────────────────────────────────────────────────────┘
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────────────────┐
|
||
│ Database (MySQL / PostgreSQL / SQL Server / SQLite / Oracle) │
|
||
│ 表前缀: fastapi_ · 软删除: is_delete │
|
||
└─────────────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
## 架构特征
|
||
|
||
:::tip 核心设计原则
|
||
遵循以下架构设计原则,确保系统在长期演进中保持高质量和可维护性:
|
||
:::
|
||
|
||
### 1. 前后端分离
|
||
|
||
前端 Vue3 应用通过 HTTP API 调用后端 FastAPI 服务,两者独立开发、独立部署。前端开发阶段通过 Vite 的 `proxy` 配置将 `/api` 请求代理到后端 `http://127.0.0.1:8031`,生产环境由 Nginx 统一反向代理。
|
||
|
||
### 2. 分层架构
|
||
|
||
后端严格分为三层,每层职责单一、依赖单向:
|
||
|
||
| 层次 | 目录 | 职责 |
|
||
|:---:|:---:|:---|
|
||
| HTTP 层 | `api/v1/endpoints/` | 路由定义、权限装饰器、参数接收、响应返回 |
|
||
| 业务层 | `modules/{group}/{name}/service.py` | 业务逻辑、校验规则、序列化加工 |
|
||
| 数据层 | `modules/{group}/{name}/repository.py` | 数据库 CRUD、查询条件组装 |
|
||
|
||
### 3. 模板方法模式
|
||
|
||
通过 `BaseRepository` 和 `BaseService` 基类,将通用 CRUD 流程固化为模板方法。子类只需声明差异点(过滤字段、排序规则、唯一性校验等),即可获得完整的增删改查能力,极大减少重复代码。
|
||
|
||
### 4. 中间件洋葱模型
|
||
|
||
请求处理采用 Starlette 中间件链,形成洋葱模型。中间件在 `src/core/app.py` 的 `create_app()` 中按以下顺序注册(Starlette 按注册反序执行,最后注册的最先处理请求):
|
||
|
||
```python
|
||
# src/core/app.py - create_app() 中间件注册顺序
|
||
app.middleware("http")(redis_middleware) # Redis 上下文注入(最内层)
|
||
app.middleware("http")(db_session_middleware) # DB 会话管理
|
||
app.middleware("http")(operation_log_middleware) # 操作日志记录
|
||
app.middleware("http")(token_refresh_middleware) # Token 续签
|
||
register_router(app) # 路由注册
|
||
app.middleware("http")(add_process_time_header) # 请求计时
|
||
app.middleware("http")(upload_size_limit_middleware) # 上传体积预拦截
|
||
app.middleware("http")(rate_limit_middleware) # 滑动窗口限流
|
||
register_cors(app) # CORS(最外层)
|
||
```
|
||
|
||
外层中间件(CORS、限流)先拦截,内层中间件(DB 会话、Redis 注入)后处理,响应沿反向链返回。限流被置于 CORS 内层,被限流的请求不进入 DB 会话与操作日志,避免 DoS 攻击时日志表与 DB 连接不降反增。
|
||
|
||
### 5. 全局异常处理
|
||
|
||
`register_exception(app)` 在 `src/core/app.py` 中注册 5 个全局异常处理器,所有异常均返回 HTTP 200 状态码,通过 `code` 字段区分业务成功(0)与失败(1):
|
||
|
||
| 异常类型 | 触发场景 | 响应格式 |
|
||
|:---|:---|:---|
|
||
| `AuthorizationException` | JWT 过期 / 无权限 | `{"code": 401, "msg": "..."}` |
|
||
| `BusinessException` | 业务逻辑错误 | `{"code": 1, "msg": "..."}` |
|
||
| `RequestValidationError` | Pydantic 校验失败 | `{"code": 1, "msg": "field: message/..."}` |
|
||
| `StarletteHTTPException` | 404 / 405 等 | `{"code": 1, "msg": "请求错误"}` |
|
||
| `Exception` | 未捕获异常 | `{"code": 1, "msg": "服务器内部错误"}` |
|
||
|
||
### 6. 统一响应格式
|
||
|
||
所有 API 端点返回统一的 JSON 结构:
|
||
|
||
```json
|
||
{
|
||
"code": 0,
|
||
"data": {},
|
||
"msg": "操作成功",
|
||
"ok": true
|
||
}
|
||
```
|
||
|
||
成功响应 `code=0`,失败响应 `code=1`,前端无需针对不同接口做差异化解析。
|
||
|
||
### 6. 软删除策略
|
||
|
||
所有业务表通过 `is_delete` 字段实现软删除(0=正常,1=已删除)。`BaseRepository` 的等值查询方法自动追加 `is_delete=0` 过滤,业务代码无需关心已删除数据。
|
||
|
||
### 7. 事务自动管理
|
||
|
||
数据库事务由 `src/middleware/db_session.py` 的 `db_session_middleware` 统一管理:为每个请求创建独立的 `SessionLocal` 实例并注入 `contextvars`,写操作(POST/PUT/DELETE/PATCH)根据响应体 `code` 字段自动 `commit`(code==0)或 `rollback`,异常时自动 rollback,finally 中关闭会话。业务代码只需调用 `model.save()` 完成 `add + flush`,无需手动提交事务。
|
||
|
||
```python
|
||
# src/middleware/db_session.py 核心逻辑
|
||
async def db_session_middleware(request: Request, call_next):
|
||
db = SessionLocal()
|
||
_db_ctx.set(db)
|
||
try:
|
||
response = await call_next(request)
|
||
if request.method in ('POST', 'PUT', 'DELETE', 'PATCH'):
|
||
body = await read_response_body(response)
|
||
if _is_business_success(body): # code == 0
|
||
db.commit()
|
||
else:
|
||
db.rollback()
|
||
return response
|
||
except Exception:
|
||
db.rollback()
|
||
raise
|
||
finally:
|
||
db.close()
|
||
```
|
||
|
||
### 8. 多数据库驱动
|
||
|
||
通过 `DB_DRIVER` 环境变量切换数据库驱动(MySQL / PostgreSQL / SQL Server / SQLite / Oracle),`SQLAlchemy` 的方言层屏蔽了底层差异,业务代码无需修改。
|
||
|
||
### 9. 应用生命周期管理
|
||
|
||
`src/core/app.py` 通过 `_combined_lifespan` 管理应用启动和关闭流程:
|
||
|
||
```python
|
||
# src/core/app.py
|
||
@asynccontextmanager
|
||
async def _combined_lifespan(app: FastAPI):
|
||
"""组合 lifespan:先起 Redis,再启动定时任务调度器;退出时先停调度器再关 Redis"""
|
||
async with redis_lifespan(app):
|
||
from modules.job.scheduler import init_scheduler, shutdown_scheduler
|
||
# init_scheduler 内部含同步 DB 查询,放入线程池执行避免阻塞启动期事件循环
|
||
job_count = await asyncio.to_thread(init_scheduler)
|
||
try:
|
||
yield
|
||
finally:
|
||
shutdown_scheduler()
|
||
```
|
||
|
||
启动顺序:`validate_config()` → `setup_logging()` → Redis 连接池 → 定时任务调度器。关闭顺序:调度器 → Redis 连接池。
|
||
|
||
## 技术分层图
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────────────────┐
|
||
│ Frontend (Vue3) │
|
||
│ AntDesign Vue · Pinia · Vue Router · Axios │
|
||
└──────────────────────────┬───────────────────────────────────┘
|
||
│ HTTP / JSON
|
||
┌──────────────────────────┴───────────────────────────────────┐
|
||
│ FastAPI Application │
|
||
│ │
|
||
│ ┌─────────────┐ ┌─────────────┐ ┌──────────────────────┐ │
|
||
│ │ Middleware │ │ Router │ │ Exception Handler │ │
|
||
│ │ ───────── │ │ ───────── │ │ ───────────────── │ │
|
||
│ │ CORS │ │ auth │ │ Authorization │ │
|
||
│ │ Redis │ │ v1 (login │ │ BusinessException │ │
|
||
│ │ RateLimit │ │ required) │ │ Validation │ │
|
||
│ │ DBSession │ │ │ │ HTTP │ │
|
||
│ │ OpLog │ │ │ │ Generic │ │
|
||
│ └─────────────┘ └─────────────┘ └──────────────────────┘ │
|
||
│ │
|
||
│ ┌──────────────────────────────────────────────────────────┐│
|
||
│ │ Endpoints (api/v1/endpoints/) ││
|
||
│ │ @permission_required · @check_demo · Pydantic Form ││
|
||
│ └──────────────────────────────────────────────────────────┘│
|
||
│ │ │
|
||
│ ┌──────────────────────────────────────────────────────────┐│
|
||
│ │ Services (modules/{group}/{name}/service.py) ││
|
||
│ │ BaseService · 自定义 Service ││
|
||
│ └──────────────────────────────────────────────────────────┘│
|
||
│ │ │
|
||
│ ┌──────────────────────────────────────────────────────────┐│
|
||
│ │ Repositories (modules/{group}/{name}/repository.py) ││
|
||
│ │ BaseRepository[Model] · 自定义 Repository ││
|
||
│ └──────────────────────────────────────────────────────────┘│
|
||
│ │ │
|
||
│ ┌──────────────────────────────────────────────────────────┐│
|
||
│ │ Models (modules/{group}/{name}/models.py) ││
|
||
│ │ base_model + base_db → SQLAlchemy ORM ││
|
||
│ └──────────────────────────────────────────────────────────┘│
|
||
└──────────────────────────┬───────────────────────────────────┘
|
||
│
|
||
┌────────────┴────────────┐
|
||
▼ ▼
|
||
┌────────────┐ ┌─────────────┐
|
||
│ Database │ │ Redis │
|
||
│ (MySQL等) │ │ (async) │
|
||
└────────────┘ └─────────────┘
|
||
```
|
||
|
||
## 总结
|
||
|
||
采用经典的前后端分离 + 三层架构设计,通过中间件链实现横切关注点(认证、限流、日志、事务)的统一处理,通过基类模板方法消除重复 CRUD 代码,通过 Pydantic 实现请求参数的声明式校验。整体架构在保持简洁的同时,具备良好的可扩展性和可维护性,适合企业级后台管理系统的快速开发与长期演进。
|