# 调试与故障排查 **本文引用的文件** - [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java) - [application.yml](file://crm-app/src/main/resources/application.yml) - [AuthApplication.java](file://crm-auth/src/main/java/com/crm/auth/AuthApplication.java) - [application.yml](file://crm-auth/src/main/resources/application.yml) - [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java) - [TraceIdFilter.java](file://crm-base/src/main/java/com/crm/base/filter/TraceIdFilter.java) - [ResultCodeEnum.java](file://crm-base/src/main/java/com/crm/base/domain/result/ResultCodeEnum.java) - [BusinessErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/BusinessErrorException.java) - [PermissionErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/PermissionErrorException.java) - [ResourceNotExistException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/ResourceNotExistException.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) - [AuthController.java](file://crm-auth/src/main/java/com/crm/auth/controller/AuthController.java) - [FileController.java](file://crm-file/src/main/java/com/crm/file/controller/FileController.java) - [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.java) - [FileProperties.java](file://crm-file/src/main/java/com/crm/file/config/FileProperties.java) - [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java) - [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构总览](#架构总览) 5. [详细组件分析](#详细组件分析) 6. [依赖关系分析](#依赖关系分析) 7. [性能注意事项](#性能注意事项) 8. [故障排查指南](#故障排查指南) 9. [结论](#结论) 10. [附录](#附录) ## 简介 本指南面向开发者和运维人员,聚焦于在 CRM 后端项目中快速定位和解决常见问题的方法。内容涵盖: - IDE 调试配置要点 - 日志分析与 TraceId 追踪机制 - 性能分析与内存泄漏检测 - 常见问题诊断与解决方案(数据库连接、权限认证失败、文件上传异常等) - 错误码对照表与排错流程 目标是帮助读者建立系统化的排障思路,缩短问题定位时间,提升交付质量。 ## 项目结构 本项目采用多模块结构,主要包含: - crm-app:应用启动入口与全局配置 - crm-auth:认证授权与安全相关能力 - crm-base:公共基础能力(异常、统一响应、过滤器、通用配置等) - crm-file:文件服务(上传、下载、预览、分片清理等) ```mermaid graph TB subgraph "应用层" APP["crm-app
应用启动"] AUTH["crm-auth
认证授权"] FILE["crm-file
文件服务"] end subgraph "基础能力" BASE["crm-base
异常/过滤器/配置"] end APP --> AUTH APP --> FILE AUTH --> BASE FILE --> BASE ``` 图表来源 - [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java) - [AuthApplication.java](file://crm-auth/src/main/java/com/crm/auth/AuthApplication.java) - [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java) - [TraceIdFilter.java](file://crm-base/src/main/java/com/crm/base/filter/TraceIdFilter.java) 章节来源 - [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java) - [AuthApplication.java](file://crm-auth/src/main/java/com/crm/auth/AuthApplication.java) - [application.yml](file://crm-app/src/main/resources/application.yml) - [application.yml](file://crm-auth/src/main/resources/application.yml) ## 核心组件 - 全局异常处理:统一捕获并返回标准错误响应,便于前端一致化处理与日志聚合。 - TraceId 过滤器:为每次请求生成或透传唯一追踪ID,贯穿跨服务调用链路。 - 安全与鉴权:基于 JWT 的认证过滤链与令牌服务,支撑登录、鉴权与数据权限控制。 - 文件服务:提供上传、下载、预览与分片清理任务,支持对象存储(如 MinIO)。 - 基础配置:数据库、缓存、序列化、分页与SQL注入器等关键基础设施。 章节来源 - [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java) - [TraceIdFilter.java](file://crm-base/src/main/java/com/crm/base/filter/TraceIdFilter.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) - [FileController.java](file://crm-file/src/main/java/com/crm/file/controller/FileController.java) - [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.java) - [FileProperties.java](file://crm-file/src/main/java/com/crm/file/config/FileProperties.java) - [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) ## 架构总览 下图展示了从请求进入、鉴权、业务处理到响应返回的关键路径,以及 TraceId 在各环节的传递方式。 ```mermaid sequenceDiagram participant Client as "客户端" participant Filter as "TraceId过滤器" participant Auth as "JWT过滤器" participant Controller as "控制器" participant Service as "服务层" participant DB as "数据库" participant Cache as "缓存" Client->>Filter : "HTTP 请求(携带或生成TraceId)" Filter-->>Client : "透传TraceId到响应头" Filter->>Auth : "放行至安全过滤器" Auth->>Auth : "校验Token/权限" Auth-->>Controller : "通过则进入控制器" Controller->>Service : "执行业务逻辑" Service->>DB : "读写数据" Service->>Cache : "读取/写入缓存" Service-->>Controller : "返回结果" Controller-->>Client : "统一响应(含TraceId)" ``` 图表来源 - [TraceIdFilter.java](file://crm-base/src/main/java/com/crm/base/filter/TraceIdFilter.java) - [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java) - [AuthController.java](file://crm-auth/src/main/java/com/crm/auth/controller/AuthController.java) - [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java) ## 详细组件分析 ### 全局异常处理与错误码 - 统一异常处理器集中捕获业务异常、参数异常、权限异常等,并转换为标准响应体,便于前端解析与日志采集。 - 错误码枚举定义了常用状态码与描述,建议新增错误时同步更新枚举与文档。 ```mermaid flowchart TD Start(["请求进入"]) --> Try["尝试执行业务逻辑"] Try --> Success{"是否抛出异常?"} Success --> |否| ReturnOK["返回成功响应"] Success --> |是| Catch["全局异常处理器捕获"] Catch --> Classify{"异常类型判断"} Classify --> |业务异常| BizErr["构造业务错误响应"] Classify --> |权限异常| PermErr["构造权限错误响应"] Classify --> |资源不存在| ResErr["构造资源不存在响应"] Classify --> |其他异常| SysErr["构造系统错误响应"] BizErr --> Log["记录错误日志(含TraceId)"] PermErr --> Log ResErr --> Log SysErr --> Log Log --> ReturnErr["返回统一错误响应"] ReturnOK --> End(["结束"]) ReturnErr --> End ``` 图表来源 - [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java) - [ResultCodeEnum.java](file://crm-base/src/main/java/com/crm/base/domain/result/ResultCodeEnum.java) - [BusinessErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/BusinessErrorException.java) - [PermissionErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/PermissionErrorException.java) - [ResourceNotExistException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/ResourceNotExistException.java) 章节来源 - [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java) - [ResultCodeEnum.java](file://crm-base/src/main/java/com/crm/base/domain/result/ResultCodeEnum.java) - [BusinessErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/BusinessErrorException.java) - [PermissionErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/PermissionErrorException.java) - [ResourceNotExistException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/ResourceNotExistException.java) ### 认证与鉴权(JWT) - 安全配置定义过滤器链与白名单策略。 - JWT 过滤器负责解析 Token、校验签名与有效期,并将用户信息注入上下文。 - Token 服务封装了 Token 的生成、刷新与校验逻辑。 ```mermaid classDiagram class SecurityConfig { +配置过滤器链() +配置白名单() } class JwtAuthenticationFilter { +doFilter(request, response, chain) -parseToken(request) -validateToken(token) } class TokenService { +generateToken(user) +refreshToken(token) +validateToken(token) } class AuthController { +login(param) +logout() } SecurityConfig --> JwtAuthenticationFilter : "注册过滤器" JwtAuthenticationFilter --> TokenService : "使用" AuthController --> TokenService : "生成/刷新Token" ``` 图表来源 - [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) - [AuthController.java](file://crm-auth/src/main/java/com/crm/auth/controller/AuthController.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) - [AuthController.java](file://crm-auth/src/main/java/com/crm/auth/controller/AuthController.java) ### 文件服务(上传/下载/预览/清理) - 文件控制器提供上传、下载、预览接口。 - 对象存储配置(如 MinIO)与文件属性(大小限制、路径规则)集中管理。 - 定时任务清理孤立的分片文件,避免磁盘膨胀。 ```mermaid sequenceDiagram participant Client as "客户端" participant FileCtrl as "文件控制器" participant FileSvc as "文件服务" participant Storage as "对象存储(MinIO)" participant Task as "分片清理任务" Client->>FileCtrl : "POST /upload" FileCtrl->>FileSvc : "处理上传(校验/落盘/元数据)" FileSvc->>Storage : "写入分片/合并文件" Storage-->>FileSvc : "返回对象地址" FileSvc-->>FileCtrl : "返回FileInfo" FileCtrl-->>Client : "返回上传结果" Note over Task,Storage : "定时扫描并清理孤立分片" ``` 图表来源 - [FileController.java](file://crm-file/src/main/java/com/crm/file/controller/FileController.java) - [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.java) - [FileProperties.java](file://crm-file/src/main/java/com/crm/file/config/FileProperties.java) - [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java) 章节来源 - [FileController.java](file://crm-file/src/main/java/com/crm/file/controller/FileController.java) - [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.java) - [FileProperties.java](file://crm-file/src/main/java/com/crm/file/config/FileProperties.java) - [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java) ### TraceId 追踪机制 - 过滤器在请求进入时生成或提取 TraceId,并将其注入响应头,便于前端与网关透传。 - 日志框架应输出 TraceId,配合日志平台进行全链路检索。 ```mermaid flowchart TD A["请求到达"] --> B{"是否存在TraceId?"} B --> |否| C["生成新TraceId"] B --> |是| D["复用现有TraceId"] C --> E["放入请求上下文"] D --> E E --> F["执行业务逻辑"] F --> G["将TraceId写入响应头"] G --> H["返回响应"] ``` 图表来源 - [TraceIdFilter.java](file://crm-base/src/main/java/com/crm/base/filter/TraceIdFilter.java) 章节来源 - [TraceIdFilter.java](file://crm-base/src/main/java/com/crm/base/filter/TraceIdFilter.java) ## 依赖关系分析 - 应用启动类加载各模块配置,启用 Web、安全、数据库、缓存等组件。 - 认证模块依赖基础模块的异常、过滤器与工具类。 - 文件模块依赖基础模块的配置与工具,并通过对象存储客户端访问外部存储。 ```mermaid graph LR APP["crm-app"] --> AUTH["crm-auth"] APP --> FILE["crm-file"] AUTH --> BASE["crm-base"] FILE --> BASE ``` 图表来源 - [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java) - [AuthApplication.java](file://crm-auth/src/main/java/com/crm/auth/AuthApplication.java) 章节来源 - [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java) - [AuthApplication.java](file://crm-auth/src/main/java/com/crm/auth/AuthApplication.java) ## 性能注意事项 - 数据库 - 合理设置连接池大小与超时,避免连接耗尽;关注慢查询与锁等待。 - 使用 MyBatis Plus 的分页与批量操作减少往返次数。 - 缓存 - 热点数据优先走缓存,注意缓存穿透、雪崩与一致性策略。 - 文件上传 - 大文件采用分片上传与断点续传,降低网络抖动影响。 - 定期清理孤立分片,防止磁盘占用增长。 - 线程与GC - 监控线程池使用率与阻塞情况;结合 GC 日志与堆转储分析内存泄漏。 - 可观测性 - 开启必要指标与链路追踪,结合 TraceId 进行问题定位。 [本节为通用指导,不直接分析具体文件] ## 故障排查指南 ### IDE 调试配置 - 本地启动 - 以 Spring Boot 应用方式运行各模块主类(如应用与认证模块)。 - 设置 JVM 参数:开启调试端口、GC 日志、堆转储开关。 - 断点与变量 - 在过滤器、控制器、服务层关键点设置断点,观察请求上下文与 TraceId。 - 条件断点用于高频场景(如特定用户或文件类型)。 - 远程调试 - 生产或测试环境开启远程调试端口,谨慎使用并确保网络安全。 [本节为通用指导,不直接分析具体文件] ### 日志分析与 TraceId 使用 - 日志级别 - 开发阶段提高日志级别,生产按需调整;敏感信息脱敏。 - 链路追踪 - 确保所有日志输出包含 TraceId;在网关、服务间透传该字段。 - 日志平台 - 使用 ELK/日志中心按 TraceId 聚合查看完整调用链。 章节来源 - [TraceIdFilter.java](file://crm-base/src/main/java/com/crm/base/filter/TraceIdFilter.java) - [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java) ### 性能分析工具使用 - CPU 热点 - 使用采样器或火焰图定位热点方法;结合慢查询日志分析 SQL。 - 内存分析 - 导出堆转储,使用分析工具检查对象持有与引用链,定位内存泄漏。 - 缓存命中率 - 监控缓存命中与过期策略,优化键设计与 TTL。 - 文件上传吞吐 - 监控 I/O 与网络带宽,评估分片大小与并发度。 [本节为通用指导,不直接分析具体文件] ### 常见问题诊断与解决方案 #### 数据库连接问题 - 现象 - 启动时报连接失败、运行时出现连接池耗尽或超时。 - 排查步骤 - 检查数据库地址、用户名、密码与网络连通性。 - 查看连接池配置(最大连接数、空闲超时、获取超时)。 - 关注慢查询与事务未释放导致的连接占用。 - 解决方案 - 修正连接参数与权限;调优连接池参数;修复长事务与未关闭的资源。 章节来源 - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [application.yml](file://crm-app/src/main/resources/application.yml) - [application.yml](file://crm-auth/src/main/resources/application.yml) #### 权限认证失败 - 现象 - 401/403 响应,提示 Token 无效或缺少权限。 - 排查步骤 - 确认请求头中是否携带有效 Token;检查 Token 签发与刷新逻辑。 - 检查安全配置白名单与角色/菜单权限映射。 - 查看全局异常处理器输出的错误码与描述。 - 解决方案 - 修复 Token 生命周期与签名配置;完善权限数据;调整白名单策略。 章节来源 - [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) - [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java) - [ResultCodeEnum.java](file://crm-base/src/main/java/com/crm/base/domain/result/ResultCodeEnum.java) #### 文件上传异常 - 现象 - 上传失败、分片丢失、预览不可用或磁盘空间不足。 - 排查步骤 - 检查文件大小限制与 MIME 类型校验。 - 验证对象存储配置(端点、桶名、密钥)与网络可达性。 - 查看分片清理任务是否正常运行,避免孤立分片堆积。 - 解决方案 - 调整上传参数与存储配置;修复分片合并逻辑;优化清理任务调度。 章节来源 - [FileController.java](file://crm-file/src/main/java/com/crm/file/controller/FileController.java) - [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.java) - [FileProperties.java](file://crm-file/src/main/java/com/crm/file/config/FileProperties.java) - [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java) #### 缓存相关问题 - 现象 - 缓存未命中、数据不一致或缓存击穿。 - 排查步骤 - 检查 Redis 连接与序列化配置;核对缓存键设计。 - 监控缓存命中率与过期策略。 - 解决方案 - 修正序列化与键命名规范;增加防击穿与降级策略。 章节来源 - [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java) ### 错误码对照表 以下为常见错误码分类与含义说明(示例),实际值以枚举为准: - 成功类 - 200:请求成功 - 参数类 - 400:参数校验失败 - 业务类 - 500:业务异常(如库存不足、状态不合法) - 权限类 - 401:未认证 - 403:无权限 - 资源类 - 404:资源不存在 - 系统类 - 500:系统内部错误 章节来源 - [ResultCodeEnum.java](file://crm-base/src/main/java/com/crm/base/domain/result/ResultCodeEnum.java) - [BusinessErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/BusinessErrorException.java) - [PermissionErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/PermissionErrorException.java) - [ResourceNotExistException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/ResourceNotExistException.java) ### 性能瓶颈分析方法 - 识别瓶颈 - 使用性能分析工具采集 CPU、内存、I/O、网络与数据库指标。 - 结合 TraceId 与日志平台定位慢调用链。 - 优化方向 - 数据库:索引优化、SQL 改写、连接池调优。 - 缓存:热点预热、合理 TTL、一致性策略。 - 文件:分片大小与并发度调优、CDN 加速。 - 代码:减少同步阻塞、避免 N+1 查询、合理使用异步。 [本节为通用指导,不直接分析具体文件] ### 内存泄漏检测技巧 - 开启 GC 日志与堆转储开关,模拟高负载场景触发问题。 - 使用分析工具检查大对象与强引用链,定位未释放资源。 - 关注第三方库版本与已知漏洞,及时升级。 [本节为通用指导,不直接分析具体文件] ## 结论 通过统一的异常处理、TraceId 追踪与完善的配置管理,项目具备良好的可观测性与可维护性。建议在日常开发与上线过程中严格执行上述调试与排障流程,结合性能分析与内存检测手段,持续提升系统稳定性与用户体验。 [本节为总结性内容,不直接分析具体文件] ## 附录 - 常用命令与脚本 - 本地启动、远程调试、GC 日志导出等命令模板。 - 参考链接 - 日志平台使用手册、性能分析工具官方文档。 [本节为补充信息,不直接分析具体文件]