Yudao项目中 Quartz 架构的使用方式
文章目录
- 前言
- 项目 Quartz 架构使用说明
- 一、整体架构图
- 二、核心组件说明
- 1. JobHandler 接口 - 任务处理器
- 2. JobHandlerInvoker - 任务调用器
- 3. SchedulerManager - 调度器管理器
- 4. JobService - 任务业务服务
- 5. JobController - 管理后台 API
- 三、数据存储结构
- 1. infra_job 表 - 任务配置表
- 2. infra_job_log 表 - 任务执行日志表
- 3. qrtz_* 表 - Quartz 集群表
- 四、使用流程完整示例
- 步骤 1:实现 JobHandler
- 步骤 2:通过管理后台创建任务
- 步骤 3:任务执行流程
- 步骤 4:管理任务
- 五、核心特性说明
- 1. 任务重试机制
- 2. 并发控制
- 3. 任务同步机制
- 六、配置说明
- 七、SRM 模块中的实际使用
- 总结
前言
Yudao项目中 Quartz 架构的使用方式。
项目 Quartz 架构使用说明
一、整体架构图
┌─────────────────────────────────────────────────────────────────────────┐ │ Quartz 架构总览 │ ├─────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────┐ ┌─────────────────────────────────────┐ │ │ │ 管理后台界面 │ ───> │ JobController (REST API) │ │ │ └─────────────────┘ └─────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────┐ │ │ │ JobService (业务服务层) │ │ │ │ - 创建/更新/删除/触发/同步任务 │ │ │ └─────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────┐ │ │ │ SchedulerManager (调度器管理) │ │ │ │ - addJob/updateJob/deleteJob │ │ │ └─────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────┐ │ │ │ Quartz Scheduler (核心调度) │ │ │ └─────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────┐ │ │ │ JobHandlerInvoker (调用器) │ │ │ │ - 继承 QuartzJobBean │ │ │ └─────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────┐ │ │ │ JobHandler (任务处理器接口) │ │ │ │ ┌───────────────────────────────┐ │ │ │ │ │ AccessLogCleanJob │ │ │ │ │ │ GetErpPurchaseJob │ │ │ │ │ │ GetErpMaterialJob │ │ │ │ │ │ ... │ │ │ │ │ └───────────────────────────────┘ │ │ │ └─────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────┐ │ │ │ JobLog (任务执行日志) │ │ │ └─────────────────────────────────────┘ │ │ │ │ │ │ 数据存储层: │ │ - infra_job (任务配置表) │ │ - infra_job_log (任务执行日志表) │ │ - qrtz_* (Quartz 集群表) │ │ │ └─────────────────────────────────────────────────────────────────────────┘二、核心组件说明
1. JobHandler 接口 - 任务处理器
文件位置:yudao-framework/yudao-spring-boot-starter-job/src/main/java/.../JobHandler.java
publicinterfaceJobHandler{/** * 执行任务 * * @param param 参数 * @return 结果 * @throws Exception 异常 */Stringexecute(Stringparam)throwsException;}使用方式:实现该接口,添加@Component注解,指定 Bean 名称
示例(访问日志清理 Job):
@Component@Slf4jpublicclassAccessLogCleanJobimplementsJobHandler{@ResourceprivateApiAccessLogServiceapiAccessLogService;@OverridepublicStringexecute(Stringparam){Integercount=apiAccessLogService.cleanAccessLog(14,100);returnString.format("定时执行清理访问日志数量 %s 个",count);}}示例(SRM 模块的 ERP 同步 Job):
@Component("getErpPurchaseJob")@Slf4jpublicclassGetErpPurchaseJobimplementsJobHandler{@OverridepublicStringexecute(Stringparam)throwsException{return"同步【物资采购申购单】结束";}}2. JobHandlerInvoker - 任务调用器
文件位置:yudao-framework/yudao-spring-boot-starter-job/src/main/java/.../JobHandlerInvoker.java
核心作用:
- 继承
QuartzJobBean,作为 Quartz 的任务执行入口 - 负责调用
JobHandler.execute()执行业务逻辑 - 记录任务执行日志
- 处理任务失败重试机制
核心注解:
@DisallowConcurrentExecution:禁止同一个任务并发执行@PersistJobDataAfterExecution:持久化 JobData 数据
3. SchedulerManager - 调度器管理器
文件位置:yudao-framework/yudao-spring-boot-starter-job/src/main/java/.../SchedulerManager.java
核心 API:
| 方法名 | 说明 |
|---|---|
addJob() | 添加 Job 到 Quartz 中 |
updateJob() | 更新 Job 配置 |
deleteJob() | 删除 Job |
pauseJob() | 暂停 Job |
resumeJob() | 恢复 Job |
triggerJob() | 立即触发 Job 一次 |
4. JobService - 任务业务服务
文件位置:yudao-module-infra/src/main/java/.../JobServiceImpl.java
核心功能:
- 任务 CRUD 管理
- 任务状态管理
- 任务同步
- 任务触发
5. JobController - 管理后台 API
文件位置:yudao-module-infra/src/main/java/.../JobController.java
提供的 REST API:
| 接口 | 说明 |
|---|---|
POST /infra/job/create | 创建定时任务 |
PUT /infra/job/update | 更新定时任务 |
PUT /infra/job/update-status | 更新任务状态(开启/暂停) |
DELETE /infra/job/delete | 删除定时任务 |
PUT /infra/job/trigger | 立即触发任务 |
POST /infra/job/sync | 同步所有任务 |
GET /infra/job/page | 任务列表分页 |
GET /infra/job/get_next_times | 查看任务下 N 次执行时间 |
三、数据存储结构
1. infra_job 表 - 任务配置表
| 字段 | 类型 | 说明 |
|---|---|---|
id | Long | 主键 |
name | String | 任务名称 |
status | Integer | 任务状态(0:初始 1:正常 2:暂停) |
handler_name | String | JobHandler Bean 名称 |
handler_param | String | 任务参数 |
cron_expression | String | CRON 表达式 |
retry_count | Integer | 重试次数 |
retry_interval | Integer | 重试间隔(毫秒) |
monitor_timeout | Integer | 监控超时时间 |
2. infra_job_log 表 - 任务执行日志表
记录每次任务执行的详细日志。
3. qrtz_* 表 - Quartz 集群表
Quartz 框架自带的表,用于存储调度状态。
四、使用流程完整示例
步骤 1:实现 JobHandler
创建一个任务处理器 Bean:
@Component("myDemoJob")@Slf4jpublicclassMyDemoJobimplementsJobHandler{@OverridepublicStringexecute(Stringparam){log.info("[execute] 我的演示任务执行,参数:{}",param);return"执行成功";}}步骤 2:通过管理后台创建任务
方式 1:通过 API 接口
POST/infra/job/create Content-Type:application/json{"name":"我的演示任务","handlerName":"myDemoJob","handlerParam":"testParam","cronExpression":"0/30 * * * * ?",// 每 30 秒执行一次"retryCount":3,"retryInterval":1000}方式 2:通过管理页面
在管理后台的「系统管理 - 定时任务」中添加任务。
步骤 3:任务执行流程
- 调度触发:Quartz 根据 Cron 表达式触发任务
- 调用 JobHandlerInvoker:调用
executeInternal()方法 - 执行任务:通过 Spring Bean 名称获取
myDemoJob,调用execute() - 记录日志:将执行结果写入
infra_job_log表 - 重试处理:如果失败,根据配置进行重试
步骤 4:管理任务
- 立即触发:调用
PUT /infra/job/trigger?id=1 - 暂停任务:调用
PUT /infra/job/update-status?id=1&status=2 - 查看日志:在管理后台查看任务执行历史
五、核心特性说明
1. 任务重试机制
JobHandlerInvoker 实现了自动重试:
privatevoidhandleException(Throwableexception,intrefireCount,intretryCount,intretryInterval){// 如果达到重试上限,抛出异常if(refireCount>=retryCount){thrownewJobExecutionException(exception);}// 未到重试上限,sleep 后重试if(retryInterval>0){ThreadUtil.sleep(retryInterval);}thrownewJobExecutionException(exception,true);// 立即重试}2. 并发控制
@DisallowConcurrentExecution// 禁止同一个任务并发执行publicclassJobHandlerInvokerextendsQuartzJobBean{// ...}3. 任务同步机制
JobService 提供syncJob()方法,用于重新同步数据库中的任务到 Quartz 调度器:
publicvoidsyncJob()throwsSchedulerException{List<JobDO>jobList=jobMapper.selectList();for(JobDOjob:jobList){schedulerManager.deleteJob(job.getHandlerName());schedulerManager.addJob(job.getId(),job.getHandlerName(),job.getHandlerParam(),job.getCronExpression(),job.getRetryCount(),job.getRetryInterval());if(Objects.equals(job.getStatus(),JobStatusEnum.STOP.getStatus())){schedulerManager.pauseJob(job.getHandlerName());}}}六、配置说明
项目使用yudao-spring-boot-starter-jobStarter 自动配置,在yudao-framework/yudao-spring-boot-starter-job/src/main/java/.../YudaoQuartzAutoConfiguration.java中定义。
@AutoConfiguration@EnableScheduling// 开启 Spring 自带的定时任务@Slf4jpublicclassYudaoQuartzAutoConfiguration{@BeanpublicSchedulerManagerschedulerManager(Optional<Scheduler>scheduler){if(!scheduler.isPresent()){log.info("[定时任务 - 已禁用][参考 https://doc.iocoder.cn/job/ 开启]");returnnewSchedulerManager(null);}returnnewSchedulerManager(scheduler.get());}}七、SRM 模块中的实际使用
SRM 模块中有大量 ERP 同步相关的 Job:
GetErpPurchaseJobGetErpMaterialJobGetErpSupplierJob- 等等…
这些 Job 都使用同样的模式:实现JobHandler接口,通过管理后台配置 CRON 表达式定时执行。
总结
项目的 Quartz 架构设计非常完善:
- 清晰的分层:接口层 -> 业务层 -> 调度层 -> 执行层
- 完整的管理功能:创建、更新、暂停、触发、同步
- 内置重试机制:任务失败自动重试
- 执行日志:完整的执行历史记录
- 动态任务:支持运行时动态添加、修改任务
建议保持当前架构,因为:
- 架构已经非常成熟完善
- 支持动态任务,这是 XXL-Job 不具备的
- 与 Infra 模块集成完善
- 管理后台功能完整
