28 KiB
28 KiB
Lyzsys 架构设计文档
📖 目录
架构概述
整体架构
Lyzsys 采用前后端分离的模块化单体架构,基于**领域驱动设计(DDD)**思想进行模块划分,支持未来向微服务架构演进。
┌─────────────────────────────────────────────────────────────────┐
│ 客户端层 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Web 浏览器 │ │ 移动 App │ │ 小程序 │ │
│ │ (Vue3) │ │ (UniApp) │ │ (UniApp) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 接入层 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Nginx / │ │ API 网关 │ │ 负载均衡 │ │
│ │ CDN │ │ (可选) │ │ │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 应用层 │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ lyzsys-server │ │
│ │ (Spring Boot 应用) │ │
│ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ │
│ │ │ Controller │ │ Service │ │ DAL │ │ │
│ │ │ 层 │ │ 层 │ │ 层 │ │ │
│ │ └────────────┘ └────────────┘ └────────────┘ │ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│
┌─────────────────────┼─────────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────────┐ ┌──────────────┐
│lyzsys-module-│ │lyzsys-module-xxx │ │lyzsys-module-│
│ system │ │ (业务模块) │ │ infra │
└──────────────┘ └──────────────────┘ └──────────────┘
│
┌─────────────────────┼─────────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────────┐ ┌──────────────┐
│lyzsys- │ │lyzsys-framework │ │lyzsys- │
│dependencies │ │ (框架组件) │ │common │
└──────────────┘ └──────────────────┘ └──────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 数据层 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ MySQL │ │ Redis │ │ MinIO │ │
│ │ (主数据库) │ │ (缓存) │ │ (文件存储) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 外部服务 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ AI 服务 │ │ 短信服务 │ │ 支付服务 │ │
│ │ (OpenAI等) │ │ (阿里云等) │ │ (微信等) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────────┘
架构特点
- 前后端分离: 前端和后端独立开发、部署、扩展
- 模块化设计: 业务模块独立,低耦合、高内聚
- 分层架构: 清晰的分层,职责明确
- 微服务就绪: 模块化设计便于微服务化改造
- 多租户支持: 原生支持 SaaS 多租户场景
- 高可用: 支持集群部署,无状态设计
架构设计原则
1. 单一职责原则 (SRP)
每个模块、每个类只负责一个职责。
示例:
UserController只负责接收 HTTP 请求UserService只负责业务逻辑处理UserMapper只负责数据库操作
2. 开闭原则 (OCP)
对扩展开放,对修改关闭。
示例:
- 通过实现接口扩展功能,而非修改原有代码
- 使用策略模式实现不同的支付方式
3. 里氏替换原则 (LSP)
子类可以替换父类。
示例:
UserServiceImpl可以替换UserServiceBaseMapperX可以替换BaseMapper
4. 接口隔离原则 (ISP)
使用多个细粒度的接口,而非单一的总接口。
示例:
UserService、RoleService、MenuService各司其职- 前端 API 按模块划分(
/system/user、/system/role)
5. 依赖倒置原则 (DIP)
高层模块不依赖低层模块,都依赖于抽象。
示例:
- Controller 依赖 Service 接口,而非实现
- Service 依赖 Mapper 接口,而非实现
6. 迪米特法则 (LoD)
最少知识原则,模块之间尽量少交互。
示例:
- 模块之间通过 API 接口交互
- 避免跨层调用(如 Controller 直接调用 Mapper)
分层架构
应用分层
┌─────────────────────────────────────────────────────────────┐
│ Controller 层 │
│ • 接收 HTTP 请求 │
│ • 参数校验 │
│ • 调用 Service 层 │
│ • 返回响应 │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Service 层 │
│ • 业务逻辑处理 │
│ • 事务控制 │
│ • 调用 DAL 层 │
│ • 返回处理结果 │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ DAL 层 │
│ • 数据访问 │
│ • 数据库操作 │
│ • 缓存操作 │
│ • 返回数据对象 │
└─────────────────────────────────────────────────────────────┘
层次交互规则
- 自上而下调用: Controller → Service → DAL
- 跨层访问: 允许 Service 直接调用多个 DAL
- 禁止反向调用: 下层不能调用上层
- 同层交互: 同层之间通过接口交互
分层示例
Controller 层
@RestController
@RequestMapping("/system/user")
@Tag(name = "管理后台 - 用户")
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/create")
@Operation(summary = "创建用户")
public CommonResult<Long> createUser(@Valid @RequestBody UserCreateReqVO reqVO) {
return success(userService.createUser(reqVO));
}
@GetMapping("/get")
@Operation(summary = "获取用户详情")
public CommonResult<UserRespVO> getUser(@RequestParam("id") Long id) {
return success(userService.getUser(id));
}
}
Service 层
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Autowired
private DeptMapper deptMapper;
@Override
@Transactional(rollbackFor = Exception.class)
public Long createUser(UserCreateReqVO reqVO) {
// 业务逻辑
UserDO user = UserConvert.INSTANCE.convert(reqVO);
userMapper.insert(user);
return user.getId();
}
@Override
public UserRespVO getUser(Long id) {
UserDO user = userMapper.selectById(id);
DeptDO dept = deptMapper.selectById(user.getDeptId());
return UserConvert.INSTANCE.convert(user, dept);
}
}
DAL 层
@Mapper
public interface UserMapper extends BaseMapperX<UserDO> {
default UserDO selectByUsername(String username) {
return selectOne("username", username);
}
default PageResult<UserDO> selectPage(UserPageReqVO pageReqVO) {
return selectPage(pageReqVO, new LambdaQueryWrapperX<UserDO>()
.likeIfPresent(UserDO::getUsername, pageReqVO.getUsername())
.betweenIfPresent(UserDO::getCreateTime, pageReqVO.getCreateTime())
.orderByDesc(UserDO::getId));
}
}
模块化设计
模块划分
项目按照**领域驱动设计(DDD)**思想进行模块划分。
基础模块
| 模块 | 职责 |
|---|---|
| lyzsys-dependencies | 依赖版本管理 |
| lyzsys-framework | 框架组件封装 |
| lyzsys-server | 应用启动入口 |
业务模块
| 模块 | 领域 | 职责 |
|---|---|---|
| lyzsys-module-system | 系统管理 | 用户、角色、菜单、部门、字典等 |
| lyzsys-module-infra | 基础设施 | 代码生成、文件、配置、任务等 |
| lyzsys-module-bpm | 工作流 | 流程定义、流程实例、任务管理 |
| lyzsys-module-pay | 支付 | 支付订单、退款、回调 |
| lyzsys-module-member | 会员 | 会员、积分、等级 |
| lyzsys-module-mall | 商城 | 商品、订单、营销 |
| lyzsys-module-crm | CRM | 客户、商机、合同 |
| lyzsys-module-erp | ERP | 采购、销售、库存 |
| lyzsys-module-ai | AI | AI 聊天、绘图、知识库 |
| lyzsys-module-mp | 微信公众号 | 公众号管理、粉丝、消息 |
| lyzsys-module-iot | IoT | 设备、产品、数据采集 |
| lyzsys-module-report | 报表 | 报表设计、大屏设计 |
模块结构
每个业务模块都遵循统一的结构:
lyzsys-module-xxx/
├── api/ # 对外 API
│ ├── xxxApi.java
│ └── xxxApiImpl.java
├── controller/ # 控制器
│ ├── admin/ # 管理后台 API
│ │ ├── xxxController.java
│ │ └── vo/
│ │ ├── xxxReqVO.java
│ │ └── xxxRespVO.java
│ └── app/ # 用户 App API
│ └── xxxController.java
├── service/ # 服务层
│ ├── xxxService.java
│ └── xxxServiceImpl.java
├── dal/ # 数据访问层
│ ├── dataobject/ # 数据对象
│ │ └── xxxDO.java
│ ├── mysql/ # MySQL Mapper
│ │ └── xxxMapper.java
│ └── redis/ # Redis DAO
│ └── xxxRedisDAO.java
├── convert/ # 对象转换
│ └── xxxConvert.java
├── enums/ # 枚举
│ └── xxxEnum.java
└── framework/ # 框架配置
└── xxxConfiguration.java
模块交互
模块间调用规则
- 禁止直接依赖: 模块之间不能直接依赖
- 通过 API 调用: 通过 API 接口进行调用
- 事件驱动: 通过消息队列进行异步通信
示例
// mall 模块调用 pay 模块
@DubboReference
private PayOrderApi payOrderApi;
public void createOrder(OrderCreateReqVO reqVO) {
// 创建订单
OrderDO order = createOrder(reqVO);
// 调用支付模块
PayOrderCreateReqDTO payReq = new PayOrderCreateReqDTO();
payReq.setOrderId(order.getId());
payOrderApi.createOrder(payReq);
}
数据架构
数据存储
┌─────────────────────────────────────────────────────────────┐
│ 数据层 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ MySQL │ │ Redis │ │ MinIO │ │
│ │ (主数据库) │ │ (缓存) │ │ (文件存储) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────┘
数据库设计
表命名规范
- 格式:
{模块}_{业务}_{实体} - 示例:
system_users、system_roles、mall_orders
字段命名规范
- 小写字母 + 下划线
- 示例:
user_id、user_name、create_time
通用字段
每张表都包含以下通用字段:
id BIGINT 主键
create_time DATETIME 创建时间
update_time DATETIME 更新时间
creator VARCHAR(64) 创建人
updater VARCHAR(64) 更新人
deleted BIT 是否删除
tenant_id BIGINT 租户 ID (多租户表)
多租户数据隔离
策略
- 共享数据库、共享 Schema: 所有租户共享数据库,通过
tenant_id隔离 - 自动过滤: MyBatis Plus 拦截器自动添加租户条件
实现
@TableName("system_users")
public class UserDO extends TenantBaseDO {
private Long id;
private String username;
// tenant_id 由 TenantBaseDO 提供
}
// 查询时自动过滤
List<UserDO> users = userMapper.selectList();
// SQL: SELECT * FROM system_users WHERE deleted = 0 AND tenant_id = ?
缓存设计
缓存策略
- 本地缓存: Caffeine(本地缓存)
- 分布式缓存: Redis(分布式缓存)
缓存使用
// 使用 Spring Cache
@Cacheable(value = "user", key = "#id")
public UserDO getUser(Long id) {
return userMapper.selectById(id);
}
// 使用 RedisTemplate
@Service
public class UserServiceImpl {
@Autowired
private RedisTemplate<String, UserDO> redisTemplate;
public UserDO getUser(Long id) {
String key = "user:" + id;
UserDO user = redisTemplate.opsForValue().get(key);
if (user == null) {
user = userMapper.selectById(id);
redisTemplate.opsForValue().set(key, user, 1, TimeUnit.HOURS);
}
return user;
}
}
安全架构
认证授权
认证流程
1. 用户登录
↓
2. 后端验证用户名密码
↓
3. 生成 JWT Token
↓
4. 返回 Token 给前端
↓
5. 前端存储 Token
↓
6. 后续请求携带 Token
↓
7. 后端验证 Token
↓
8. 允许访问
授权模型
用户 (User)
↓
角色 (Role)
↓
权限 (Permission)
↓
资源 (Resource)
数据权限
权限范围
| 权限范围 | 说明 |
|---|---|
| 全部数据权限 | 查看所有数据 |
| 本部门数据权限 | 只能查看本部门数据 |
| 本部门及以下数据权限 | 查看本部门及子部门数据 |
| 仅本人数据权限 | 只能查看自己的数据 |
| 自定义数据权限 | 自定义数据权限规则 |
实现
@DataScope(deptAlias = "d", userAlias = "u")
public List<UserDO> getUserList() {
return userMapper.selectList();
}
// SQL 自动添加
// AND (d.id = ? OR d.id IN (?, ?) OR u.id = ?)
API 安全
接口加密
// 请求加密
@PostMapping("/create")
public CommonResult<Long> createUser(@RequestBody String encryptedData) {
// 解密
String json = decrypt(encryptedData);
UserCreateReqVO reqVO = JSON.parseObject(json, UserCreateReqVO.class);
// 业务处理
Long id = userService.createUser(reqVO);
// 加密返回
return success(encrypt(id));
}
接口签名
// 请求签名
@PostMapping("/create")
public CommonResult<Long> createUser(
@RequestHeader("X-Signature") String signature,
@RequestBody UserCreateReqVO reqVO
) {
// 验证签名
if (!verifySignature(signature, reqVO)) {
return error(401, "签名验证失败");
}
// 业务处理
return success(userService.createUser(reqVO));
}
技术架构
技术选型
后端技术栈
| 技术 | 版本 | 用途 |
|---|---|---|
| Spring Boot | 2.7.18 | 应用框架 |
| Spring Security | 5.8.16 | 安全框架 |
| MyBatis Plus | 3.5.15 | ORM 框架 |
| Flowable | 6.8.0 | 工作流引擎 |
| Quartz | 2.3.2 | 定时任务 |
| Redisson | 3.52.0 | 分布式锁 |
| Knife4j | 3.0.3 | API 文档 |
前端技术栈
| 技术 | 版本 | 用途 |
|---|---|---|
| Vue | 3.2+ | 前端框架 |
| TypeScript | 4.x | 类型系统 |
| Vite | 4.x | 构建工具 |
| Element Plus | 2.x | UI 组件库 |
| Pinia | 2.x | 状态管理 |
框架封装
Web 封装
- 全局异常处理
- 统一响应格式
- 请求日志记录
- 参数校验
安全封装
- JWT 认证
- 权限注解
- 数据权限
- API 加密
数据库封装
- BaseMapperX
- LambdaQueryWrapperX
- 分页插件
- 租户插件
部署架构
单机部署
┌─────────────────────────────────────────────────────────────┐
│ 服务器 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Nginx │ │ JDK 8 │ │ MySQL │ │
│ │ (前端) │ │ (后端) │ │ (数据库) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Redis │ │ MinIO │ │
│ │ (缓存) │ │ (文件存储) │ │
│ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────┘
集群部署
┌─────────────────────────────────────────────────────────────┐
│ 负载均衡 │
│ (Nginx / F5) │
└─────────────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 应用服务器 1 │ │ 应用服务器 2 │ │ 应用服务器 3 │
│ (后端服务) │ │ (后端服务) │ │ (后端服务) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
└────────────────┼────────────────┘
▼
┌─────────────────┐
│ MySQL 主从 │
│ Redis 集群 │
└─────────────────┘
容器化部署
┌─────────────────────────────────────────────────────────────┐
│ Kubernetes 集群 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Pod 1 │ │ Pod 2 │ │ Pod 3 │ │
│ │ (后端服务) │ │ (后端服务) │ │ (后端服务) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ MySQL │ │ Redis │ │ MinIO │ │
│ │ (StatefulSet)│ │ (StatefulSet)│ │ (Deployment)│ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────┘
性能优化
数据库优化
- 索引优化: 合理创建索引
- SQL 优化: 避免全表扫描
- 分页查询: 使用分页插件
- 读写分离: 主从数据库配置
- 连接池: Druid 连接池优化
缓存优化
- 本地缓存: Caffeine 本地缓存
- 分布式缓存: Redis 缓存
- 缓存预热: 系统启动时加载热点数据
- 缓存更新: 定时更新缓存
接口优化
- 批量操作: 批量插入、批量更新
- 异步处理: 消息队列异步处理
- 接口合并: 减少请求次数
- 压缩传输: Gzip 压缩
前端优化
- 代码分割: 路由懒加载
- 资源压缩: Gzip、Brotli 压缩
- CDN 加速: 静态资源 CDN
- 浏览器缓存: 合理设置缓存策略
扩展性设计
水平扩展
- 应用集群: 多台应用服务器
- 数据库集群: 主从、分库分表
- 缓存集群: Redis 集群
- 文件存储: 分布式文件系统
垂直扩展
- 升级硬件: CPU、内存、磁盘
- 优化配置: JVM、数据库参数
微服务化
- 模块拆分: 按业务模块拆分
- 服务注册: Nacos、Eureka
- 服务调用: Dubbo、Feign
- 网关路由: Spring Cloud Gateway
文档版本: v1.0.0 最后更新: 2025-01-19 维护团队: Lyzsys 架构团队