# 定时任务 **本文引用的文件** - [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java) - [application.yml](file://crm-app/src/main/resources/application.yml) - [ScheduledTaskProperties.java](file://crm-base/src/main/java/com/crm/base/config/ScheduledTaskProperties.java) - [SchedulingConfig.java](file://crm-file/src/main/java/com/crm/file/config/SchedulingConfig.java) - [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java) - [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java) - [FileApiImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileApiImpl.java) - [KkFileViewClient.java](file://crm-file/src/main/java/com/crm/file/service/KkFileViewClient.java) - [FileInfoMapper.java](file://crm-file/src/main/java/com/crm/file/mapper/FileInfoMapper.java) - [FileInfo.java](file://crm-file/src/main/java/com/crm/file/domain/entity/FileInfo.java) - [FileConstants.java](file://crm-file/src/main/java/com/crm/file/constant/FileConstants.java) - [FileController.java](file://crm-file/src/main/java/com/crm/file/controller/FileController.java) ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构总览](#架构总览) 5. [详细组件分析](#详细组件分析) 6. [依赖关系分析](#依赖关系分析) 7. [性能考虑](#性能考虑) 8. [故障排查指南](#故障排查指南) 9. [结论](#结论) 10. [附录](#附录) ## 简介 本指南面向在 Spring Boot 项目中开发定时任务的工程师,围绕 Spring Schedule 的核心概念(@Scheduled、Cron 表达式、调度器配置)展开,并结合本项目中的 OrphanChunkCleanupTask 示例,系统讲解文件清理任务的实现模式与最佳实践。内容涵盖: - 任务定义与调度配置 - Cron 表达式设计与参数化 - 异常处理与日志记录规范 - 分布式环境下的任务分片、负载均衡与故障转移方案 - 监控与运维方法(执行状态查看、性能分析与问题排查) ## 项目结构 本项目采用多模块组织,定时任务相关代码主要位于 crm-file 模块中,基础能力与通用配置位于 crm-base 模块,应用入口位于 crm-app 模块。关键路径如下: - 应用启动类:crm-app - 定时任务配置与属性:crm-base、crm-file - 定时任务实现与依赖服务:crm-file ```mermaid graph TB subgraph "应用层" APP["crm-app
应用入口"] end subgraph "基础能力" BASE["crm-base
通用配置/属性"] end subgraph "文件服务" FILE["crm-file
文件业务/定时任务"] end APP --> FILE APP --> BASE FILE --> BASE ``` **图表来源** - [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java) - [ScheduledTaskProperties.java](file://crm-base/src/main/java/com/crm/base/config/ScheduledTaskProperties.java) - [SchedulingConfig.java](file://crm-file/src/main/java/com/crm/file/config/SchedulingConfig.java) **章节来源** - [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java) - [application.yml](file://crm-app/src/main/resources/application.yml) - [ScheduledTaskProperties.java](file://crm-base/src/main/java/com/crm/base/config/ScheduledTaskProperties.java) - [SchedulingConfig.java](file://crm-file/src/main/java/com/crm/file/config/SchedulingConfig.java) ## 核心组件 - 调度器配置与属性 - 通过 @EnableScheduling 启用 Spring Schedule - 使用自定义属性类集中管理调度开关、线程池大小、默认 Cron 等 - 定时任务类 - 以 @Scheduled 注解声明任务,支持 fixedDelay/fixedRate/cron - 结合属性注入实现可配置的调度策略 - 业务服务与数据访问 - 任务调用 Service/Mapper 完成数据查询与清理逻辑 - 通过事务边界控制一致性 **章节来源** - [SchedulingConfig.java](file://crm-file/src/main/java/com/crm/file/config/SchedulingConfig.java) - [ScheduledTaskProperties.java](file://crm-base/src/main/java/com/crm/base/config/ScheduledTaskProperties.java) - [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java) ## 架构总览 下图展示了定时任务从调度到执行的端到端流程,包括调度器、任务类、服务层与数据访问层的交互。 ```mermaid sequenceDiagram participant Scheduler as "Spring 调度器" participant Task as "OrphanChunkCleanupTask" participant FileService as "FileInfoServiceImpl" participant Mapper as "FileInfoMapper" participant DB as "数据库" Scheduler->>Task : "按 Cron/固定间隔触发" Task->>Task : "参数校验与日志记录" Task->>FileService : "执行清理逻辑" FileService->>Mapper : "查询待清理的碎片" Mapper->>DB : "SELECT/DELETE" DB-->>Mapper : "结果集" Mapper-->>FileService : "实体列表" FileService->>FileService : "批量删除/状态更新" FileService-->>Task : "返回执行结果" Task-->>Scheduler : "完成并记录耗时/异常" ``` **图表来源** - [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java) - [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java) - [FileInfoMapper.java](file://crm-file/src/main/java/com/crm/file/mapper/FileInfoMapper.java) ## 详细组件分析 ### 调度器与属性配置 - 启用调度 - 在配置类中使用 @EnableScheduling 开启 Spring Schedule - 可通过自定义线程池配置提升并发处理能力 - 属性驱动 - 使用 ScheduledTaskProperties 统一暴露调度开关、线程池大小、默认 Cron 等 - 在 application.yml 中配置具体值,便于环境与部署差异化管理 ```mermaid classDiagram class SchedulingConfig { +enableScheduling() +taskExecutor() } class ScheduledTaskProperties { +enabled : boolean +poolSize : int +defaultCron : String } SchedulingConfig --> ScheduledTaskProperties : "读取配置" ``` **图表来源** - [SchedulingConfig.java](file://crm-file/src/main/java/com/crm/file/config/SchedulingConfig.java) - [ScheduledTaskProperties.java](file://crm-base/src/main/java/com/crm/base/config/ScheduledTaskProperties.java) **章节来源** - [SchedulingConfig.java](file://crm-file/src/main/java/com/crm/file/config/SchedulingConfig.java) - [ScheduledTaskProperties.java](file://crm-base/src/main/java/com/crm/base/config/ScheduledTaskProperties.java) - [application.yml](file://crm-app/src/main/resources/application.yml) ### 定时任务实现:OrphanChunkCleanupTask - 任务职责 - 定期扫描并清理“孤儿”上传分片文件,释放存储资源 - 执行要点 - 使用 @Scheduled(cron = "${...}") 或 fixedDelay/fixedRate - 在任务入口处进行参数校验与日志记录 - 将清理逻辑委托给 FileInfoServiceImpl,保证事务一致性与错误隔离 - 异常处理 - 捕获并记录异常,避免单次失败影响后续调度 - 对部分失败场景进行重试或告警(建议结合外部监控) ```mermaid flowchart TD Start(["任务开始"]) --> CheckEnabled["检查调度开关与参数"] CheckEnabled --> Query["查询待清理的分片记录"] Query --> HasData{"是否有数据?"} HasData --> |否| End(["结束"]) HasData --> |是| BatchDelete["批量删除分片记录"] BatchDelete --> UpdateStatus["更新关联文件状态"] UpdateStatus --> LogResult["记录执行结果与耗时"] LogResult --> End ``` **图表来源** - [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java) - [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java) **章节来源** - [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java) - [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java) - [FileInfoMapper.java](file://crm-file/src/main/java/com/crm/file/mapper/FileInfoMapper.java) - [FileInfo.java](file://crm-file/src/main/java/com/crm/file/domain/entity/FileInfo.java) - [FileConstants.java](file://crm-file/src/main/java/com/crm/file/constant/FileConstants.java) ### 数据模型与接口 - 数据模型 - FileInfo 表示文件信息,包含分片数量、状态、时间戳等字段 - 接口与实现 - FileInfoMapper 提供数据访问能力 - FileInfoServiceImpl 封装业务逻辑,供定时任务调用 ```mermaid erDiagram FILE_INFO { bigint id PK string file_name int chunk_count int completed_chunks enum status timestamp created_at timestamp updated_at } ``` **图表来源** - [FileInfo.java](file://crm-file/src/main/java/com/crm/file/domain/entity/FileInfo.java) **章节来源** - [FileInfo.java](file://crm-file/src/main/java/com/crm/file/domain/entity/FileInfo.java) - [FileInfoMapper.java](file://crm-file/src/main/java/com/crm/file/mapper/FileInfoMapper.java) - [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java) ### 与文件服务的集成 - 文件控制器 - FileController 暴露上传、下载、预览等接口 - 文件 API 客户端 - KkFileViewClient 用于在线预览等第三方能力 - 文件 API 实现 - FileApiImpl 封装文件操作的业务细节 ```mermaid graph LR Controller["FileController"] --> ApiImpl["FileApiImpl"] ApiImpl --> Client["KkFileViewClient"] ApiImpl --> Service["FileInfoServiceImpl"] Service --> Mapper["FileInfoMapper"] ``` **图表来源** - [FileController.java](file://crm-file/src/main/java/com/crm/file/controller/FileController.java) - [FileApiImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileApiImpl.java) - [KkFileViewClient.java](file://crm-file/src/main/java/com/crm/file/service/KkFileViewClient.java) - [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java) - [FileInfoMapper.java](file://crm-file/src/main/java/com/crm/file/mapper/FileInfoMapper.java) **章节来源** - [FileController.java](file://crm-file/src/main/java/com/crm/file/controller/FileController.java) - [FileApiImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileApiImpl.java) - [KkFileViewClient.java](file://crm-file/src/main/java/com/crm/file/service/KkFileViewClient.java) - [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java) - [FileInfoMapper.java](file://crm-file/src/main/java/com/crm/file/mapper/FileInfoMapper.java) ## 依赖关系分析 - 模块内依赖 - OrphanChunkCleanupTask 依赖 FileInfoServiceImpl,后者依赖 FileInfoMapper - SchedulingConfig 依赖 ScheduledTaskProperties - 外部依赖 - 数据库(MyBatis-Plus)、对象存储(MinIO)等由其他配置类管理 ```mermaid graph TB Task["OrphanChunkCleanupTask"] --> Service["FileInfoServiceImpl"] Service --> Mapper["FileInfoMapper"] Config["SchedulingConfig"] --> Props["ScheduledTaskProperties"] ``` **图表来源** - [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java) - [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java) - [FileInfoMapper.java](file://crm-file/src/main/java/com/crm/file/mapper/FileInfoMapper.java) - [SchedulingConfig.java](file://crm-file/src/main/java/com/crm/file/config/SchedulingConfig.java) - [ScheduledTaskProperties.java](file://crm-base/src/main/java/com/crm/base/config/ScheduledTaskProperties.java) **章节来源** - [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java) - [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java) - [FileInfoMapper.java](file://crm-file/src/main/java/com/crm/file/mapper/FileInfoMapper.java) - [SchedulingConfig.java](file://crm-file/src/main/java/com/crm/file/config/SchedulingConfig.java) - [ScheduledTaskProperties.java](file://crm-base/src/main/java/com/crm/base/config/ScheduledTaskProperties.java) ## 性能考虑 - 调度频率与批处理 - 合理设置 Cron 或 fixedDelay,避免频繁扫描造成数据库压力 - 采用分批查询与批量删除,减少锁竞争与网络往返 - 线程池与并发 - 根据任务耗时与 CPU/IO 特性调整线程池大小 - 对 IO 密集型任务适当增大线程数,CPU 密集型任务保持较小线程数 - 索引与 SQL 优化 - 为查询条件字段建立合适索引,避免全表扫描 - 避免 N+1 查询,尽量使用 JOIN 或批量操作 - 幂等与重试 - 确保清理逻辑具备幂等性,防止重复执行导致数据不一致 - 对短暂失败场景设计退避重试策略 [本节为通用指导,不直接分析具体文件] ## 故障排查指南 - 常见问题定位 - 任务未执行:检查 @EnableScheduling 是否生效、Cron 表达式是否正确、调度开关是否关闭 - 执行缓慢:查看慢查询日志、SQL 执行计划、线程池占用情况 - 数据不一致:确认事务边界与回滚策略,检查并发写入冲突 - 日志与监控 - 在任务入口与关键步骤记录结构化日志(含任务名、批次大小、耗时、异常堆栈) - 接入 APM/指标采集(如 Prometheus),监控任务执行次数、成功率、平均耗时 - 恢复与自愈 - 对可恢复错误实施自动重试;对不可恢复错误进行告警并人工介入 - 提供手动触发接口或脚本,便于紧急清理 **章节来源** - [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java) - [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java) ## 结论 通过统一的调度配置与属性驱动,结合清晰的任务分层与事务边界,本项目实现了稳定可靠的文件清理定时任务。在生产环境中,应重点关注调度频率、批处理策略、索引优化与监控告警,以确保系统在大规模数据场景下仍具备良好的性能与稳定性。 [本节为总结性内容,不直接分析具体文件] ## 附录 - Cron 表达式速查 - 秒 分 时 日 月 周 - 常用示例:每5分钟执行一次、每天凌晨2点执行、工作日每隔1小时执行 - 分布式调度建议 - 使用分布式任务平台(如 XXL-Job、ElasticJob、Quartz 集群)实现分片与高可用 - 基于 Redis 分布式锁实现简单分片与互斥执行 - 结合健康检查与故障转移,确保单点故障不影响整体调度 [本节为概念性内容,不直接分析具体文件]