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