Files
novalon-manage-system/docs/plans/2026-03-13-multi-module-architecture-refactor-design.md
T
张翔 dc53a233b9 refactor(domain): 将领域模型移动到common模块
重构项目结构,将分散在各模块的领域模型统一移动到manage-common模块
更新相关依赖和引用路径
调整docker-compose配置和测试标记
添加新的Playwright测试配置
优化Dockerfile构建过程
2026-03-13 19:58:57 +08:00

24 KiB
Raw Blame History

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 结构

{
  "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. 从请求头提取 TokenAuthorization: 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 路由权限映射

/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 缓存策略

缓存配置

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 连接池

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 版本)

@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 配置

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 文件

# 数据库配置
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 应用监控端点

文档结束