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.
314 lines
14 KiB
314 lines
14 KiB
|
1 month ago
|
# 定时任务
|
||
|
|
|
||
|
|
<cite>
|
||
|
|
**本文引用的文件**
|
||
|
|
- [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)
|
||
|
|
</cite>
|
||
|
|
|
||
|
|
## 目录
|
||
|
|
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<br/>应用入口"]
|
||
|
|
end
|
||
|
|
subgraph "基础能力"
|
||
|
|
BASE["crm-base<br/>通用配置/属性"]
|
||
|
|
end
|
||
|
|
subgraph "文件服务"
|
||
|
|
FILE["crm-file<br/>文件业务/定时任务"]
|
||
|
|
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 分布式锁实现简单分片与互斥执行
|
||
|
|
- 结合健康检查与故障转移,确保单点故障不影响整体调度
|
||
|
|
|
||
|
|
[本节为概念性内容,不直接分析具体文件]
|