refactor(domain): 将领域模型移动到common模块

重构项目结构,将分散在各模块的领域模型统一移动到manage-common模块
更新相关依赖和引用路径
调整docker-compose配置和测试标记
添加新的Playwright测试配置
优化Dockerfile构建过程
This commit is contained in:
张翔
2026-03-13 19:58:57 +08:00
parent 9aed900408
commit dc53a233b9
174 changed files with 11206 additions and 2296 deletions
@@ -0,0 +1,933 @@
# Novalon Manage System 单体多模块架构重构设计文档
**文档版本**: 1.0
**创建日期**: 2026-03-13
**设计目标**: 将 novalon-manage-api 重构为单体多模块架构,实现模块化、统一认证授权、独立部署和性能优化
---
## 1. 架构概述
### 1.1 设计原则
基于参考项目 `everything-is-suitable-api` 的成功实践,novalon-manage-system 将采用**网关 + 单体多模块**的架构模式。
**核心设计原则**
1. **职责单一**:每个模块只负责一个业务领域
2. **依赖单向**:上层模块依赖下层模块,避免循环依赖
3. **接口隔离**:通过网关统一对外暴露API,内部模块解耦
4. **可测试性**:每个模块都可以独立进行单元测试和集成测试
### 1.2 架构图
```
┌─────────────────────────────────────────────────────────────────┐
│ 前端应用 (Vue 3) │
└──────────────────────┬──────────────────────────────────────┘
┌─────────────────┐
│ manage-gateway │ 8080 (网关)
│ (网关) │
└────────┬────────┘
┌─────────────────┐
│ manage-app │ 8081 (后台管理应用)
│ (业务应用) │
└────────┬────────┘
┌────────────┼────────────┐
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│manage-sys│ │manage- │ │manage- │
│(系统管理)│ │audit │ │notify │
└──────────┘ └──────────┘ └──────────┘
│ │ │
└────────────┼────────────┘
┌────────────┼────────────┐
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│manage- │ │manage- │ │manage- │
│common │ │db │ │file │
│(公共模块)│ │(数据库) │ │(文件管理)│
└──────────┘ └──────────┘ └──────────┘
┌─────────────────┐
│ PostgreSQL │
│ (数据库) │
└─────────────────┘
```
---
## 2. 模块设计
### 2.1 模块层次结构
```
novalon-manage-api/
├── manage-gateway/ # 网关层(8080端口)
│ ├── 路由配置
│ ├── JWT认证过滤器
│ ├── RBAC权限过滤器
│ └── 限流熔断
├── manage-app/ # 应用层(8081端口)
│ ├── 应用启动器
│ ├── 业务模块聚合
│ └── 配置管理
├── manage-sys/ # 系统管理模块
│ ├── 用户管理
│ ├── 角色管理
│ ├── 菜单管理
│ ├── 权限管理
│ ├── 字典管理
│ └── 系统配置
├── manage-audit/ # 审计中心模块
│ ├── 操作日志
│ ├── 登录日志
│ ├── 异常日志
│ └── 安全审计
├── manage-notify/ # 通知中心模块
│ ├── 通知公告
│ ├── 用户消息
│ └── WebSocket实时推送
├── manage-file/ # 文件管理模块
│ ├── 文件上传
│ ├── 文件下载
│ └── 文件预览
├── manage-common/ # 公共模块
│ ├── 工具类
│ ├── JWT工具
│ ├── RBAC过滤器
│ ├── 通用配置
│ └── 缓存配置
└── manage-db/ # 数据库模块
├── 实体类
├── Repository
├── DAO层
└── 数据库迁移
```
### 2.2 模块依赖关系
```
manage-gateway
manage-app
┌─────────┬─────────┬─────────┬─────────┐
│manage- │manage- │manage- │manage- │
│sys │audit │notify │file │
└────┬────┴────┬────┴────┬────┴────┬────┘
│ │ │ │
└─────────┴─────────┴─────────┘
┌─────────┴─────────┐
│manage-common │
└─────────┬─────────┘
manage-db
```
### 2.3 端口分配
- **manage-gateway**: 8080(对外统一入口)
- **manage-app**: 8081(后台管理应用)
- **PostgreSQL**: 5432(数据库)
---
## 3. 认证授权机制
### 3.1 JWT 认证流程
```
1. 用户登录
前端 → Gateway → manage-app → manage-sys
验证用户名密码
生成 JWT Token(包含用户ID、角色、权限)
返回 Token 给前端
2. 后续请求
前端 → Gateway(携带 Token
JWT 认证过滤器验证 Token
解析用户信息(ID、角色、权限)
RBAC 权限过滤器验证权限
转发到 manage-app
```
### 3.2 JWT Token 结构
```json
{
"sub": "user_123", // 用户ID
"username": "admin", // 用户名
"roles": ["ADMIN"], // 角色列表
"permissions": [ // 权限列表
"user:read",
"user:write",
"user:delete",
"role:read",
"role:write"
],
"iat": 1234567890, // 签发时间
"exp": 1234571490 // 过期时间
}
```
### 3.3 RBAC 权限模型
**角色定义**
- **SUPER_ADMIN**: 超级管理员,拥有所有权限
- **ADMIN**: 管理员,拥有系统管理权限
- **AUDITOR**: 审计员,拥有查看权限
- **OPERATOR**: 操作员,拥有基础操作权限
**权限映射**
```
用户管理:
- user:read # 查看用户
- user:write # 创建/修改用户
- user:delete # 删除用户
角色管理:
- role:read # 查看角色
- role:write # 创建/修改角色
- role:delete # 删除角色
菜单管理:
- menu:read # 查看菜单
- menu:write # 创建/修改菜单
- menu:delete # 删除菜单
系统配置:
- config:read # 查看配置
- config:write # 修改配置
审计中心:
- audit:read # 查看审计日志
通知中心:
- notice:read # 查看通知
- notice:write # 发布通知
文件管理:
- file:read # 查看文件
- file:write # 上传文件
- file:delete # 删除文件
```
### 3.4 网关认证授权流程
**Gateway 过滤器链**
```
请求 → 限流过滤器 → JWT 认证过滤器 → RBAC 权限过滤器 → 路由转发
```
**JWT 认证过滤器**
1. 从请求头提取 Token`Authorization: Bearer {token}`
2. 验证 Token 签名和有效期
3. 解析 Token 获取用户信息
4. 将用户信息添加到请求头:`X-User-Id`, `X-User-Roles`, `X-User-Permissions`
5. 验证失败返回 401 Unauthorized
**RBAC 权限过滤器**
1. 从请求头获取用户权限
2. 根据请求路径和方法判断所需权限
3. 验证用户是否拥有所需权限
4. 验证失败返回 403 Forbidden
### 3.5 路由权限映射
```java
/api/sys/users/** user:read (GET), user:write (POST/PUT), user:delete (DELETE)
/api/sys/roles/** role:read (GET), role:write (POST/PUT), role:delete (DELETE)
/api/sys/menus/** menu:read (GET), menu:write (POST/PUT), menu:delete (DELETE)
/api/sys/config/** config:read (GET), config:write (POST/PUT)
/api/audit/logs/** audit:read (GET)
/api/notify/notices/** notice:read (GET), notice:write (POST/PUT)
/api/file/files/** file:read (GET), file:write (POST), file:delete (DELETE)
```
### 3.6 Token 刷新机制
**刷新策略**
- Access Token 有效期:2 小时
- Refresh Token 有效期:7 天
- 前端在 Access Token 过期前 5 分钟使用 Refresh Token 刷新
**刷新流程**
```
前端 → Gateway → manage-app → manage-sys
验证 Refresh Token
生成新的 Access Token
返回新 Token
```
### 3.7 安全增强措施
1. **Token 加密**:使用强加密算法(RS256
2. **Token 黑名单**:使用 Caffeine 缓存存储已注销的 Token
3. **IP 绑定**:可选将 Token 与用户 IP 绑定
4. **设备指纹**:记录登录设备,异常登录时告警
5. **限流保护**:防止暴力破解(登录接口限流:5次/分钟)
---
## 4. 数据流和缓存策略
### 4.1 数据访问架构
**分层设计**
```
Handler 层(API接口)
Service 层(业务逻辑)
Repository 层(数据访问)
DAO 层(数据库操作)
PostgreSQL 数据库
```
### 4.2 Caffeine 缓存策略
**缓存配置**
```yaml
spring:
cache:
type: caffeine
caffeine:
spec: maximumSize=10000,expireAfterWrite=10m
```
**缓存分层**
1. **用户信息缓存**
- 缓存键:`user:{userId}`
- 缓存内容:用户基本信息、角色、权限
- 过期时间:5 分钟
- 最大容量:1000 条
2. **角色权限缓存**
- 缓存键:`role:{roleId}`
- 缓存内容:角色信息、关联权限
- 过期时间:10 分钟
- 最大容量:500 条
3. **菜单树缓存**
- 缓存键:`menu:tree:{userId}`
- 缓存内容:用户可访问的菜单树
- 过期时间:10 分钟
- 最大容量:1000 条
4. **字典数据缓存**
- 缓存键:`dict:{dictType}`
- 缓存内容:字典类型对应的字典数据
- 过期时间:30 分钟
- 最大容量:2000 条
5. **系统配置缓存**
- 缓存键:`config:{configKey}`
- 缓存内容:系统配置项
- 过期时间:30 分钟
- 最大容量:500 条
6. **Token 黑名单缓存**
- 缓存键:`token:blacklist:{tokenId}`
- 缓存内容:已注销的 Token ID
- 过期时间:Token 剩余有效期
- 最大容量:10000 条
### 4.3 缓存更新策略
**Cache-Aside 模式**
```
读取数据:
1. 先查缓存
2. 缓存命中,直接返回
3. 缓存未命中,查数据库
4. 将数据写入缓存
5. 返回数据
写入数据:
1. 先更新数据库
2. 删除相关缓存
3. 下次读取时重新加载缓存
```
**缓存失效场景**
- 用户信息更新 → 删除用户缓存
- 角色权限变更 → 删除角色缓存、用户缓存
- 菜单配置变更 → 删除菜单树缓存
- 字典数据变更 → 删除字典缓存
- 系统配置变更 → 删除配置缓存
- 用户登出 → 添加 Token 到黑名单缓存
### 4.4 数据流示例
**用户登录流程**
```
1. 前端请求登录
POST /api/auth/login
2. Gateway 验证(限流检查)
3. manage-app 接收请求
4. manage-sys 验证用户名密码
5. 查询用户信息(先查缓存,未命中查数据库)
6. 查询用户角色和权限(先查缓存,未命中查数据库)
7. 生成 JWT Token
8. 返回 Token 和用户信息
9. 缓存用户信息(5分钟)
```
**获取用户菜单流程**
```
1. 前端请求菜单
GET /api/sys/menus
2. Gateway 验证 JWT Token
3. Gateway 验证 RBAC 权限(menu:read
4. manage-app 接收请求
5. manage-sys 查询菜单树
6. 先查缓存(menu:tree:{userId}
7. 缓存命中,直接返回
8. 缓存未命中,查询数据库
9. 构建菜单树
10. 写入缓存(10分钟)
11. 返回菜单树
```
### 4.5 数据库连接池配置
**R2DBC 连接池**
```yaml
spring:
r2dbc:
pool:
initial-size: 10 # 初始连接数
max-size: 50 # 最大连接数
max-idle-time: 30m # 最大空闲时间
max-life-time: 1h # 连接最大生命周期
acquire-timeout: 5s # 获取连接超时时间
```
### 4.6 性能优化策略
1. **批量查询优化**
- 使用 IN 查询替代循环查询
- 使用 JOIN 减少数据库往返
2. **索引优化**
- 用户表:username, email, phone
- 角色表:role_code
- 菜单表:parent_id, menu_type
- 日志表:create_time, user_id
3. **分页查询优化**
- 使用游标分页(基于 ID
- 避免 OFFSET 过大
4. **异步处理**
- 日志记录异步化
- 消息推送异步化
5. **响应式编程**
- 使用 WebFlux 非阻塞 I/O
- 使用 R2DBC 非阻塞数据库访问
### 4.7 Token 黑名单实现(Caffeine 版本)
```java
@Configuration
public class TokenBlacklistConfig {
@Bean
public Cache<String, Boolean> tokenBlacklistCache() {
return Caffeine.newBuilder()
.maximumSize(10000)
.expireAfterWrite(2, TimeUnit.HOURS) // 与 Access Token 过期时间一致
.build();
}
}
@Service
public class TokenBlacklistService {
@Autowired
private Cache<String, Boolean> tokenBlacklistCache;
public void addToBlacklist(String tokenId) {
tokenBlacklistCache.put(tokenId, true);
}
public boolean isBlacklisted(String tokenId) {
return tokenBlacklistCache.getIfPresent(tokenId) != null;
}
}
```
---
## 5. 部署方案
### 5.1 Docker 部署架构
**容器化架构**
```
┌─────────────────────────────────────────────────────────────────┐
│ Docker Network │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Nginx │ │ Gateway │ │ App │ │
│ │ :80 │ │ :8080 │ │ :8081 │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │ │ │ │
│ └─────────────────┴─────────────────┘ │
│ │ │
│ ┌────────┴────────┐ │
│ │ PostgreSQL │ │
│ │ :5432 │ │
│ └────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
```
### 5.2 Docker Compose 配置
```yaml
version: '3.8'
services:
# PostgreSQL 数据库
postgres:
image: postgres:15-alpine
container_name: novalon-postgres
environment:
POSTGRES_DB: novalon_manage
POSTGRES_USER: ${DB_USERNAME:-postgres}
POSTGRES_PASSWORD: ${DB_PASSWORD:-postgres}
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
- ./docs/sql:/docker-entrypoint-initdb.d
networks:
- novalon-network
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
# 网关服务
manage-gateway:
build:
context: ./novalon-manage-api
dockerfile: manage-gateway/Dockerfile
container_name: novalon-gateway
ports:
- "8080:8080"
environment:
SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE:-prod}
JWT_SECRET: ${JWT_SECRET}
JWT_EXPIRATION: ${JWT_EXPIRATION:-7200}
APP_SERVICE_URL: http://manage-app:8081
depends_on:
manage-app:
condition: service_healthy
networks:
- novalon-network
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
interval: 30s
timeout: 10s
retries: 3
# 应用服务
manage-app:
build:
context: ./novalon-manage-api
dockerfile: manage-app/Dockerfile
container_name: novalon-app
ports:
- "8081:8081"
environment:
SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE:-prod}
DB_HOST: postgres
DB_PORT: 5432
DB_NAME: novalon_manage
DB_USERNAME: ${DB_USERNAME:-postgres}
DB_PASSWORD: ${DB_PASSWORD:-postgres}
JWT_SECRET: ${JWT_SECRET}
depends_on:
postgres:
condition: service_healthy
networks:
- novalon-network
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8081/actuator/health"]
interval: 30s
timeout: 10s
retries: 3
# Nginx 反向代理(可选)
nginx:
image: nginx:alpine
container_name: novalon-nginx
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/ssl:/etc/nginx/ssl
depends_on:
- manage-gateway
networks:
- novalon-network
volumes:
postgres_data:
networks:
novalon-network:
driver: bridge
```
### 5.3 环境变量配置
**.env 文件**
```bash
# 数据库配置
DB_USERNAME=postgres
DB_PASSWORD=your_secure_password
# JWT 配置
JWT_SECRET=your_jwt_secret_key_minimum_256_bits
JWT_EXPIRATION=7200
# Spring Profile
SPRING_PROFILES_ACTIVE=prod
```
---
## 6. 迁移计划
### 6.1 阶段一:准备工作(1-2天)
**Task 1: 创建新模块结构**
- 创建 manage-gateway 模块
- 创建 manage-app 模块
- 创建 manage-common 模块
- 创建 manage-db 模块
- 创建 manage-audit 模块
- 创建 manage-notify 模块
- 创建 manage-file 模块
**Task 2: 配置父 POM**
- 更新父 POM 添加新模块
- 配置依赖管理
- 配置插件管理
**Task 3: 数据库迁移准备**
- 备份现有数据库
- 检查 Flyway 迁移脚本
- 准备新的迁移脚本
### 6.2 阶段二:模块拆分(3-5天)
**Task 4: 提取公共模块(manage-common**
- 提取工具类到 manage-common
- 提取 JWT 工具类
- 提取 RBAC 过滤器
- 提取通用配置
- 提取缓存配置
**Task 5: 提取数据库模块(manage-db**
- 提取实体类到 manage-db
- 提取 Repository 接口
- 提取 DAO 层
- 提取数据库迁移脚本
**Task 6: 拆分系统管理模块(manage-sys)**
- 保留用户、角色、菜单、权限、字典、配置功能
- 移除审计、通知、文件相关代码
- 更新依赖关系
**Task 7: 创建审计中心模块(manage-audit**
- 迁移操作日志功能
- 迁移登录日志功能
- 迁移异常日志功能
- 迁移安全审计功能
**Task 8: 创建通知中心模块(manage-notify**
- 迁移通知公告功能
- 迁移用户消息功能
- 迁移 WebSocket 实时推送功能
**Task 9: 创建文件管理模块(manage-file**
- 迁移文件上传功能
- 迁移文件下载功能
- 迁移文件预览功能
### 6.3 阶段三:网关和应用层(2-3天)
**Task 10: 创建网关模块(manage-gateway**
- 配置路由规则
- 实现 JWT 认证过滤器
- 实现 RBAC 权限过滤器
- 实现限流熔断
- 配置健康检查
**Task 11: 创建应用模块(manage-app**
- 创建应用启动器
- 配置模块聚合
- 配置应用配置
- 配置 Actuator 端点
**Task 12: 配置模块依赖**
- 配置 manage-app 依赖所有业务模块
- 配置业务模块依赖 manage-db 和 manage-common
- 验证依赖关系正确性
### 6.4 阶段四:测试和优化(2-3天)
**Task 13: 单元测试**
- 为每个模块编写单元测试
- 确保测试覆盖率 ≥ 80%
- 修复测试失败
**Task 14: 集成测试**
- 测试网关路由
- 测试认证授权
- 测试模块间调用
- 测试缓存功能
**Task 15: 性能测试**
- 使用 K6 进行性能测试
- 优化慢查询
- 优化缓存策略
- 调整 JVM 参数
**Task 16: 安全测试**
- OWASP 依赖检查
- SQL 注入测试
- XSS 测试
- CSRF 测试
### 6.5 阶段五:部署和切换(1-2天)
**Task 17: Docker 部署**
- 编写 Dockerfile
- 编写 docker-compose.yml
- 配置环境变量
- 本地部署测试
**Task 18: 生产部署**
- 备份生产环境
- 部署新版本
- 验证功能正常
- 监控系统运行
**Task 19: 灰度切换**
- 切换部分流量到新版本
- 监控错误率和性能
- 逐步扩大流量
- 全量切换
**Task 20: 回滚准备**
- 准备回滚脚本
- 验证回滚流程
- 文档化回滚步骤
---
## 7. 风险控制
### 7.1 风险识别
1. **数据丢失风险**:迁移过程中数据不一致
2. **功能回归风险**:模块拆分导致功能异常
3. **性能下降风险**:网关层增加延迟
4. **部署失败风险**Docker 部署出现问题
### 7.2 风险缓解
1. **数据备份**:迁移前完整备份数据库
2. **充分测试**:单元测试、集成测试、E2E 测试
3. **灰度发布**:逐步切换流量,监控指标
4. **快速回滚**:准备回滚方案,确保可以快速恢复
---
## 8. 监控指标
### 8.1 应用监控
- 健康检查:`/actuator/health`
- 性能指标:`/actuator/metrics`
- JVM 指标:内存、GC、线程
### 8.2 业务监控
- 请求成功率
- 响应时间(P50, P95, P99
- 错误率
- 并发用户数
### 8.3 数据库监控
- 连接池使用率
- 慢查询数量
- 数据库 CPU 使用率
---
## 9. 技术栈
### 9.1 后端技术栈
- **Java**: 21
- **Spring Boot**: 3.4.1
- **Spring WebFlux**: 响应式编程框架
- **Spring Security**: 安全框架
- **Spring Data R2DBC**: 响应式数据库访问
- **PostgreSQL**: 关系型数据库
- **Flyway**: 数据库版本管理
- **JWT**: 无状态认证
- **Caffeine**: 本地缓存
- **MapStruct**: 对象映射
- **Lombok**: 简化代码
### 9.2 构建和部署
- **Maven**: 项目构建工具
- **Docker**: 容器化
- **Docker Compose**: 容器编排
- **Nginx**: 反向代理
### 9.3 测试和监控
- **JUnit 5**: 单元测试框架
- **Reactor Test**: 响应式测试
- **K6**: 性能测试
- **Spring Boot Actuator**: 应用监控
- **SpotBugs**: 静态代码分析
- **OWASP Dependency Check**: 依赖安全检查
- **JaCoCo**: 代码覆盖率
---
## 10. 成功标准
### 10.1 功能验收标准
- ✅ 所有现有功能正常工作
- ✅ 网关路由正确转发请求
- ✅ JWT 认证正常工作
- ✅ RBAC 权限控制正确
- ✅ 缓存功能正常工作
- ✅ WebSocket 实时推送正常
### 10.2 性能指标
- ✅ API 响应时间 P95 < 200ms
- ✅ API 响应时间 P99 < 500ms
- ✅ 请求成功率 > 99.9%
- ✅ 数据库连接池使用率 < 80%
- ✅ 缓存命中率 > 70%
### 10.3 质量指标
- ✅ 单元测试覆盖率 ≥ 80%
- ✅ 集成测试覆盖率 ≥ 60%
- ✅ 无严重安全漏洞
- ✅ 无严重代码质量问题
---
## 11. 后续优化方向
### 11.1 短期优化(1-3个月)
- 引入 API 文档自动生成
- 完善监控告警系统
- 优化慢查询
- 增加缓存命中率
### 11.2 中期优化(3-6个月)
- 引入分布式追踪(如 Jaeger
- 实现灰度发布功能
- 优化数据库索引
- 实现 API 版本管理
### 11.3 长期优化(6-12个月)
- 考虑微服务化改造
- 引入服务网格(如 Istio
- 实现多租户支持
- 引入事件驱动架构
---
## 附录
### A. 参考资料
- everything-is-suitable-api 双应用架构文档
- Spring Boot 官方文档
- Spring Security 官方文档
- PostgreSQL 官方文档
- Caffeine 官方文档
### B. 术语表
- **RBAC**: Role-Based Access Control,基于角色的访问控制
- **JWT**: JSON Web TokenJSON 格式的 Web Token
- **R2DBC**: Reactive Relational Database Connectivity,响应式数据库连接
- **Caffeine**: 高性能 Java 缓存库
- **Flyway**: 数据库迁移工具
- **Actuator**: Spring Boot 应用监控端点
---
**文档结束**
File diff suppressed because it is too large Load Diff