Quartz
一、基础概念
Quartz 调度框架使用
Quartz 是跨平台的开源任务调度框架,支持复杂调度规则、持久化存储和集群部署。以下是核心使用指南:
1. 核心概念
- Job:任务接口,实现
execute()
定义业务逻辑。 - Trigger:触发器,定义调度规则(如
SimpleTrigger
单次执行、CronTrigger
复杂时间表)。 - Scheduler:调度器,绑定
Job
和Trigger
并管理任务生命周期。
2. 配置示例(Java)
基础任务调度:
// 创建 Job
public class SampleJob implements Job {public void execute(JobExecutionContext context) {System.out.println("任务执行时间: " + new Date());}
}// 配置调度
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
Scheduler scheduler = schedulerFactory.getScheduler();JobDetail job = JobBuilder.newJob(SampleJob.class).withIdentity("job1", "group1").build();Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ?")) // 每5秒执行.build();scheduler.scheduleJob(job, trigger);
scheduler.start();
持久化配置(quartz.properties
):
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.dataSource = myDS
org.quartz.dataSource.myDS.driver = com.mysql.cj.jdbc.Driver
org.quartz.dataSource.myDS.URL = jdbc:mysql://localhost:3306/quartz_db
org.quartz.dataSource.myDS.user = root
org.quartz.dataSource.myDS.password = 123456
需预先创建数据库表(脚本位于 Quartz 安装包的
docs/dbTables
目录)。
3. 常见问题
Q1:任务未按预期执行?
- 检查
cron
表达式语法(如0 0 12 * * ?
表示每天中午执行)。 - 确认调度器已启动
scheduler.start()
。
Q2:集群模式下任务重复执行?
- 确保所有节点使用相同数据库和
instanceId
配置(推荐org.quartz.scheduler.instanceId = AUTO
)。
Q3:任务阻塞如何解决?
- 设置
@DisallowConcurrentExecution
注解防止同一任务并发执行。 - 增加线程池大小:
org.quartz.threadPool.threadCount = 10
4. 安全与最佳实践
- 安全机制:通过
quartz.properties
配置访问权限:org.quartz.scheduler.rmi.export = false # 禁用远程调用
- 监控:集成
JMX
或使用Quartz Monitor
实时查看任务状态。
提示:.NET Core 项目可通过
Quartz.NET
包实现类似功能,需配置依赖注入。
思维导图
二、Quartz 原理、源码
Quartz 原理、源码与组件详解
1. Quartz 核心原理
Quartz 采用 调度器-任务-触发器 三级架构:
- 调度器(Scheduler):中央控制器,管理任务生命周期和线程池。
- 任务(Job):实现
Job
接口的类,定义业务逻辑(如execute()
方法)。 - 触发器(Trigger):基于时间或事件驱动,决定任务执行时机(如
CronTrigger
支持复杂时间规则)。
执行流程:
- 调度器监听触发器状态变化。
- 当触发器满足条件时,从线程池分配线程执行关联的
Job.execute()
。 - 若配置持久化,任务状态实时同步到数据库。
2. 源码结构分析
Quartz 核心源码包(以 quartz-2.3.2
为例):
org.quartz
├── core // 核心调度逻辑
│ ├── QuartzScheduler.java // 调度器主入口
│ └── JobRunShell.java // 任务执行环境封装
├── impl // 具体实现
│ ├── StdSchedulerFactory.java // 调度器工厂
│ └── JobDetailImpl.java // JobDetail 实现类
├── jobs // 内置任务(如 NoOpJob)
├── triggers // 触发器实现
│ ├── SimpleTriggerImpl.java // 简单触发器
│ └── CronTriggerImpl.java // Cron 表达式触发器
└── utils // 工具类(如 DB 连接管理)
关键设计模式:
- 工厂模式:
StdSchedulerFactory
创建调度器实例。 - 建造者模式:
JobBuilder
/TriggerBuilder
链式构造对象。 - 责任链模式:任务执行时的异常处理链。
3. 常用注解说明
注解 | 作用 |
---|---|
@DisallowConcurrentExecution | 禁止同一任务并发执行(防止重复调度) |
@PersistJobDataAfterExecution | 任务执行后持久化 JobDataMap 中的数据(用于状态传递) |
示例:
@DisallowConcurrentExecution
@PersistJobDataAfterExecution
public class StatefulJob implements Job { public void execute(JobExecutionContext context) { JobDataMap dataMap = context.getJobDetail().getJobDataMap(); int count = dataMap.getInt("count", 0); dataMap.put("count", count + 1); // 状态持久化 }
}
4. 主要组件功能与特点
组件 | 功能 | 特点 |
---|---|---|
JobDetail | 定义任务实例的元数据(如名称、组、关联的 Job 类) | 与 Job 解耦,支持参数传递(JobDataMap) |
Trigger | 触发任务执行的条件 | 支持 SimpleTrigger (固定间隔)和 CronTrigger (复杂时间规则) |
Scheduler | 绑定 JobDetail 与 Trigger,管理任务生命周期 | 支持集群模式、任务暂停/恢复/删除 |
JobStore | 任务存储机制(内存或数据库) | RAMJobStore (高性能内存存储)、JobStoreTX (数据库事务存储) |
组件交互流程:
5. 示例代码展示
动态创建 Cron 任务:
public class DynamicScheduler { public static void addJob(Scheduler scheduler, String jobName, String cron) throws SchedulerException { JobDetail job = JobBuilder.newJob(LogJob.class) .withIdentity(jobName, "logGroup") .usingJobData("logPath", "/var/log/app.log") .build(); CronTrigger trigger = TriggerBuilder.newTrigger() .withIdentity(jobName + "Trigger", "logGroup") .withSchedule(CronScheduleBuilder.cronSchedule(cron)) .build(); scheduler.scheduleJob(job, trigger); }
} // 使用示例
scheduler.addJob(scheduler, "dailyLog", "0 0 2 * * ?"); // 每天凌晨2点执行
监听任务执行事件:
public class JobListener implements org.quartz.JobListener { @Override public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) { if (jobException != null) { System.err.println("任务执行失败: " + jobException.getMessage()); } else { System.out.println("任务成功执行于: " + new Date()); } }
} // 注册监听器
scheduler.getListenerManager().addJobListener(new JobListener());
关键总结
- 原理:调度器监听触发器 → 触发任务执行 → 持久化状态。
- 源码:核心包
org.quartz
下分模块实现调度、存储、工具等功能。 - 注解:
@DisallowConcurrentExecution
解决并发问题,@PersistJobDataAfterExecution
实现状态传递。 - 组件:
JobDetail
(任务元数据)、Trigger
(触发规则)、Scheduler
(调度中枢)协同工作。