一、Quartz 核心概念
概念 | 说明 |
---|---|
Scheduler | 调度器,负责管理任务和触发器的执行 |
Job | 任务接口,定义需要执行的具体逻辑(实现 execute 方法) |
JobDetail | 任务的元数据(Job 的配置信息,如名称、组、关联的 Job 类) |
Trigger | 触发器,定义任务执行的时间规则(如 Cron 表达式、固定间隔等) |
JobStore | 任务存储方式(内存或数据库持久化) |
ThreadPool | 线程池配置,控制任务执行的并发性 |
二、Spring Boot 整合 Quartz
1. 添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
2. 定义 Job 类
实现 Job
接口,定义任务逻辑:
public class MyJob implements Job {
@Override
public void execute(JobExecutionContext context) {
System.out.println("Job executed at: " + new Date());
}
}
3. 配置 Quartz
创建 QuartzConfig
类,定义 JobDetail
和 Trigger
:
@Configuration
public class QuartzConfig {
// 定义 JobDetail
@Bean
public JobDetail myJobDetail() {
return JobBuilder.newJob(MyJob.class)
.withIdentity("myJob", "group1")
.storeDurably() // 持久化任务
.build();
}
// 定义 Trigger(Cron 表达式)
@Bean
public Trigger myJobTrigger() {
return TriggerBuilder.newTrigger()
.forJob(myJobDetail())
.withIdentity("myTrigger", "group1")
.withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ?")) // 每 5 秒执行
.build();
}
}
三、动态管理任务
Quartz 支持运行时动态增删改任务:
1. 注入 Scheduler
@Autowired
private Scheduler scheduler;
2. 动态添加任务
public void addDynamicJob(String jobName, String group, String cron) throws SchedulerException {
JobDetail jobDetail = JobBuilder.newJob(MyJob.class)
.withIdentity(jobName, group)
.build();
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity(jobName + "Trigger", group)
.withSchedule(CronScheduleBuilder.cronSchedule(cron))
.build();
scheduler.scheduleJob(jobDetail, trigger);
}
3. 暂停/恢复任务
// 暂停任务
scheduler.pauseJob(JobKey.jobKey(jobName, group));
// 恢复任务
scheduler.resumeJob(JobKey.jobKey(jobName, group));
四、持久化任务到数据库
Quartz 支持将任务存储到数据库,避免任务丢失:
1. 添加数据库配置
在 application.properties
中配置:
# 使用 JDBC JobStore
spring.quartz.job-store-type=jdbc
# 配置数据源
spring.datasource.url=jdbc:mysql://localhost:3306/quartz
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 初始化 Quartz 表结构
spring.quartz.jdbc.initialize-schema=always
2. 初始化数据库表
Quartz 需要特定的表结构,SQL 文件可在 Quartz 官网 下载。
五、集群配置
在分布式环境中,Quartz 集群通过数据库锁实现任务协调:
# 启用集群模式
spring.quartz.properties.org.quartz.jobStore.isClustered=true
spring.quartz.properties.org.quartz.jobStore.clusterCheckinInterval=20000
spring.quartz.properties.org.quartz.scheduler.instanceId=AUTO
六、常见问题
1. Job 类无法序列化
-
原因:持久化到数据库时,Job 类需实现
Serializable
。 -
解决:确保 Job 类实现
Serializable
接口。
2. 事务管理
-
在 Job 中调用 Spring Bean 时,需确保事务生效。可以通过
@Transactional
注解或编程式事务。
七、完整示例
// Job 类
public class EmailJob implements Job {
@Override
public void execute(JobExecutionContext context) {
// 发送邮件的逻辑
System.out.println("Sending email at: " + new Date());
}
}
// 动态任务管理
@Service
public class JobService {
@Autowired
private Scheduler scheduler;
public void scheduleEmailJob(String cron) throws SchedulerException {
JobDetail jobDetail = JobBuilder.newJob(EmailJob.class)
.withIdentity("emailJob", "notification")
.build();
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("emailTrigger", "notification")
.withSchedule(CronScheduleBuilder.cronSchedule(cron))
.build();
scheduler.scheduleJob(jobDetail, trigger);
}
}
八、Quartz vs Spring @Scheduled
特性 | Quartz | Spring @Scheduled |
---|---|---|
任务持久化 | ✅ 支持 | ❌ 仅内存 |
分布式集群 | ✅ 支持 | ❌ 不支持 |
动态任务管理 | ✅ 支持 | ❌ 需自行实现 |
复杂度 | 较高 | 简单 |
适用场景 | 企业级复杂调度需求 | 简单定时任务 |