# 性能优化 **本文引用的文件** - [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java) - [application.yml](file://crm-app/src/main/resources/application.yml) - [AuthProperties.java](file://crm-auth/src/main/java/com/crm/auth/config/AuthProperties.java) - [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java) - [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java) - [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java) - [DeptTreeCache.java](file://crm-auth/src/main/java/com/crm/auth/service/DeptTreeCache.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java) - [PageConverter.java](file://crm-base/src/main/java/com/crm/base/utils/PageConverter.java) - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/base/service/impl/BaseServiceImpl.java) - [FileApiImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileApiImpl.java) - [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.java) ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构总览](#架构总览) 5. [详细组件分析](#详细组件分析) 6. [依赖关系分析](#依赖关系分析) 7. [性能考量](#性能考量) 8. [故障排查指南](#故障排查指南) 9. [结论](#结论) 10. [附录](#附录) ## 简介 本指南面向应用层面的性能优化,覆盖数据库查询、内存管理、线程池配置、HTTP层优化(压缩、缓存、连接池)、分页查询优化(以 PageConverter 为例)以及 JVM 调优与监控。文档结合代码仓库中的实际实现,给出可落地的策略与最佳实践,并附带可视化图示帮助理解。 ## 项目结构 本项目采用多模块结构: - crm-app:应用启动入口与全局配置 - crm-auth:认证授权与安全相关能力 - crm-base:通用基础能力(MyBatis-Plus、Redis、工具类、分页转换等) - crm-file:文件服务(对象存储集成、上传下载、预览) ```mermaid graph TB subgraph "应用" APP["crm-app
启动与配置"] end subgraph "认证授权" AUTH["crm-auth
安全、鉴权、令牌、权限"] end subgraph "基础能力" BASE["crm-base
MyBatis-Plus、Redis、工具类"] end subgraph "文件服务" FILE["crm-file
对象存储、上传下载"] end APP --> AUTH APP --> BASE APP --> FILE AUTH --> BASE FILE --> BASE ``` **图表来源** - [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java) - [application.yml](file://crm-app/src/main/resources/application.yml) **章节来源** - [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java) - [application.yml](file://crm-app/src/main/resources/application.yml) ## 核心组件 - 认证与令牌:JWT 过滤器、令牌服务、安全配置 - 数据访问:MyBatis-Plus 配置、通用 Service 基类 - 缓存:部门树缓存、Redis 配置 - 分页转换:PageConverter 将分页结果转换为统一 DTO - 文件服务:MinIO 客户端与上传下载流程 **章节来源** - [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java) - [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java) - [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java) - [DeptTreeCache.java](file://crm-auth/src/main/java/com/crm/auth/service/DeptTreeCache.java) - [PageConverter.java](file://crm-base/src/main/java/com/crm/base/utils/PageConverter.java) - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/base/service/impl/BaseServiceImpl.java) - [FileApiImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileApiImpl.java) - [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.java) ## 架构总览 下图展示请求从进入 Spring Security 到数据访问与缓存的关键路径,体现认证、权限、分页与缓存的交互。 ```mermaid sequenceDiagram participant Client as "客户端" participant Filter as "JwtAuthenticationFilter" participant SecCfg as "SecurityConfig" participant TokenSvc as "TokenService" participant Svc as "业务服务(BaseServiceImpl)" participant DB as "数据库(MyBatis-Plus)" participant Cache as "Redis/本地缓存(DeptTreeCache)" Client->>Filter : "HTTP 请求(携带Token)" Filter->>SecCfg : "校验白名单/放行规则" Filter->>TokenSvc : "解析并验证Token" TokenSvc-->>Filter : "用户上下文" Filter-->>Client : "通过或拒绝" Client->>Svc : "调用分页接口" Svc->>DB : "分页查询(PageHelper/MP)" DB-->>Svc : "分页结果" Svc->>Cache : "可选读取部门树/字典等" Cache-->>Svc : "缓存命中或未命中" Svc-->>Client : "返回分页响应" ``` **图表来源** - [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java) - [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java) - [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java) - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/base/service/impl/BaseServiceImpl.java) - [DeptTreeCache.java](file://crm-auth/src/main/java/com/crm/auth/service/DeptTreeCache.java) ## 详细组件分析 ### 认证与令牌链路(JWT) - 过滤器负责拦截请求、提取 Token、校验签名与过期时间,并将用户信息注入上下文 - 令牌服务提供生成、解析、刷新等能力 - 安全配置定义放行路径、异常处理、跨域等 ```mermaid classDiagram class JwtAuthenticationFilter { +doFilter(request, response, chain) -validateToken(token) -setAuthentication(context) } class TokenService { +generateToken(user) +parseToken(token) +refreshToken(token) -verifySignature(token) } class SecurityConfig { +configure(http) +permitAllPaths() +exceptionHandling() } JwtAuthenticationFilter --> TokenService : "解析/校验" JwtAuthenticationFilter --> SecurityConfig : "按规则放行" ``` **图表来源** - [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java) - [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java) - [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java) **章节来源** - [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java) - [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java) - [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java) ### 数据访问与分页(MyBatis-Plus + BaseServiceImpl) - MyBatis-Plus 提供分页插件与通用 Mapper/Service - BaseServiceImpl 封装常用 CRUD 与分页逻辑,减少样板代码 - 建议配合索引、只取必要字段、避免 N+1 查询 ```mermaid flowchart TD Start(["分页请求"]) --> BuildQuery["构建查询条件"] BuildQuery --> ApplyPagination["应用分页参数"] ApplyPagination --> ExecuteQuery["执行SQL(仅必要字段)"] ExecuteQuery --> MapResult["映射为DTO/VO"] MapResult --> ReturnResp["返回分页结果"] ``` **图表来源** - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/base/service/impl/BaseServiceImpl.java) **章节来源** - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/base/service/impl/BaseServiceImpl.java) ### 分页转换(PageConverter) - 将数据库分页对象转换为统一的分页 DTO,便于前端消费 - 建议:控制每页大小上限、避免大对象序列化、按需加载关联数据 ```mermaid flowchart TD In(["原始分页对象"]) --> Validate["校验分页参数"] Validate --> Convert["字段映射/类型转换"] Convert --> Enrich["补充元数据(总数/页码)"] Enrich --> Out(["标准分页响应"]) ``` **图表来源** - [PageConverter.java](file://crm-base/src/main/java/com/crm/base/utils/PageConverter.java) **章节来源** - [PageConverter.java](file://crm-base/src/main/java/com/crm/base/utils/PageConverter.java) ### 缓存(部门树与 Redis) - 部门树缓存用于高频读场景,降低数据库压力 - Redis 配置用于分布式缓存与会话共享 ```mermaid classDiagram class DeptTreeCache { +getDeptTree() -buildTree(depts) -refreshIfNeeded() } class RedisConfig { +redisTemplate() +cacheManager() } DeptTreeCache ..> RedisConfig : "可选使用Redis" ``` **图表来源** - [DeptTreeCache.java](file://crm-auth/src/main/java/com/crm/auth/service/DeptTreeCache.java) - [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java) **章节来源** - [DeptTreeCache.java](file://crm-auth/src/main/java/com/crm/auth/service/DeptTreeCache.java) - [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java) ### 文件服务(MinIO) - MinIO 客户端配置连接池、超时与重试 - FileApiImpl 封装上传、分片、下载与预览流程 ```mermaid sequenceDiagram participant Client as "客户端" participant FileApi as "FileApiImpl" participant Minio as "MinIO客户端" Client->>FileApi : "上传/下载请求" FileApi->>Minio : "建立连接/读写对象" Minio-->>FileApi : "流式响应/状态" FileApi-->>Client : "返回结果/流" ``` **图表来源** - [FileApiImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileApiImpl.java) - [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.java) **章节来源** - [FileApiImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileApiImpl.java) - [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.java) ## 依赖关系分析 - 认证模块依赖基础模块(工具、配置) - 文件模块依赖基础模块(配置、工具) - 启动模块聚合各功能模块 ```mermaid graph LR APP["crm-app"] --> AUTH["crm-auth"] APP --> BASE["crm-base"] APP --> FILE["crm-file"] AUTH --> BASE FILE --> BASE ``` **图表来源** - [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java) **章节来源** - [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java) ## 性能考量 ### 应用层面优化 - 数据库查询优化 - 精准选择字段,避免 SELECT * - 合理使用索引,关注慢查询与全表扫描 - 避免 N+1 查询,使用批量查询或 JOIN 替代循环查询 - 分页限制最大页大小,防止超大结果集 - 参考实现位置:[MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java)、[BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/base/service/impl/BaseServiceImpl.java) - 内存管理 - 控制对象创建与复用,避免临时大对象 - 合理设置分页大小,减少一次性加载的数据量 - 及时释放资源(流、连接),避免内存泄漏 - 参考实现位置:[PageConverter.java](file://crm-base/src/main/java/com/crm/base/utils/PageConverter.java) - 线程池配置 - Web 容器线程池:根据 CPU 核数与 IO 比例调整 - 异步任务线程池:区分 CPU 密集与 IO 密集任务 - 队列容量与拒绝策略:避免 OOM 与请求丢失 - 监控指标:活跃线程、队列长度、拒绝次数 ### HTTP 层面优化 - 响应压缩 - 启用 GZIP 压缩,减少带宽占用 - 对静态资源与 JSON 响应进行压缩 - 缓存策略 - 浏览器缓存:合理设置 Cache-Control、ETag - 服务端缓存:Redis/本地缓存热点数据(如部门树) - 参考实现位置:[DeptTreeCache.java](file://crm-auth/src/main/java/com/crm/auth/service/DeptTreeCache.java)、[RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java) - 连接池配置 - 数据库连接池:最小/最大连接数、空闲超时、获取超时 - HTTP 客户端连接池:最大连接数、连接超时、请求超时 - 参考实现位置:[application.yml](file://crm-app/src/main/resources/application.yml)、[MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.java) ### 分页查询优化(以 PageConverter 为例) - 限制每页大小,避免一次性返回过多数据 - 仅查询必要字段,减少序列化开销 - 对关联数据采用懒加载或分批加载 - 在缓存层命中后直接返回,减少数据库压力 - 参考实现位置:[PageConverter.java](file://crm-base/src/main/java/com/crm/base/utils/PageConverter.java) ### JVM 调优建议 - 堆内存配置 - 初始堆与最大堆:根据应用峰值与可用内存设定 - 新生代与老年代比例:默认通常较合理,必要时微调 - GC 策略 - 优先使用 G1GC 或 ZGC(JDK17+),降低停顿时间 - 观察 GC 日志,定位频繁 Full GC 的原因 - 监控指标 - 堆使用率、GC 次数与耗时、线程池活跃度、慢查询数量 - 使用 APM 与 Profiler(Arthas、VisualVM)定位瓶颈 ### 性能测试与瓶颈定位 - 压测工具 - JMeter:模拟并发请求,观察吞吐与延迟 - wrk/ab:HTTP 层快速压测 - 定位技巧 - 开启慢查询日志,分析 SQL 执行计划 - 使用 Arthas 在线诊断方法耗时与锁竞争 - 检查线程栈,识别阻塞点与死锁 - 对比不同分页大小与缓存命中率的影响 ## 故障排查指南 - 常见问题 - 高延迟:检查数据库慢查询、连接池耗尽、GC 停顿 - 内存溢出:排查大对象、未关闭流、缓存无界增长 - 认证失败:检查 Token 签名、过期时间、过滤器链顺序 - 排查步骤 - 查看应用日志与错误堆栈 - 采集 JVM 快照与线程 dump - 分析数据库执行计划与索引使用情况 - 逐步缩小范围,隔离问题模块 **章节来源** - [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java) - [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java) ## 结论 通过合理的数据库查询优化、内存与线程池配置、HTTP 层压缩与缓存、以及 JVM 调优与监控,可以显著提升系统吞吐与稳定性。分页查询与缓存是常见瓶颈点,应重点优化。建议在上线前进行压测与性能基线评估,持续监控与迭代优化。 ## 附录 - 关键配置参考 - 应用配置:[application.yml](file://crm-app/src/main/resources/application.yml) - 认证属性:[AuthProperties.java](file://crm-auth/src/main/java/com/crm/auth/config/AuthProperties.java) - 安全配置:[SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java) - 数据访问:[MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - 缓存配置:[RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java) - 文件服务:[MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.java)