pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
myjob
public class MyJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("MyJob"+new Date());
}
}
main方法
public static void main(String[] args) {
JobDetail jobDetail = JobBuilder.newJob(MyJob.class)
.withIdentity("job1", "group1").build();
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "trigger1")
.startNow()
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1)
.repeatForever())
.build();
try {
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.scheduleJob(jobDetail,trigger);
scheduler.start();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
使用jobDataMap
public class MyJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
JobDataMap triggerMap = jobExecutionContext.getTrigger().getJobDataMap();
System.out.println("jobDataMap:" + jobDataMap.get("job"));
System.out.println("triggerMap:" + triggerMap.get("trigger"));
JobDataMap mergeMap = jobExecutionContext.getMergedJobDataMap();
System.out.println("mergeMap :" + mergeMap.get("trigger"));//key相同的话会覆盖
}
}
public static void main(String[] args) {
JobDetail jobDetail = JobBuilder.newJob(MyJob.class)
.withIdentity("job1", "group1")
.usingJobData("job","jobDetail")//赋值
.build();
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "trigger1")
.usingJobData("trigger","trigger")//赋值
.startNow()
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1)
.repeatForever())
.build();
try {
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.scheduleJob(jobDetail,trigger);
scheduler.start();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
job并发和持久化
@DisallowConcurrentExecution
禁止并发地执行同一个job定义(jobDetail定义的)的多个实例
@PersistJobDataAfterExecution
持久化JobDetail中的JobDataMap(对trigger中的dataMap无效)如果一个任务不是持久化的,则当没有触发器关联它的时候,Quartz会从Schedule中删除它
@DisallowConcurrentExecution
@PersistJobDataAfterExecution
public class MyJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
JobDataMap dataMap = jobExecutionContext.getTrigger().getJobDataMap();
dataMap.put("count",dataMap.getInt("count")+1);
System.out.println(dataMap.getInt("count"));
JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
jobDataMap.put("count",jobDataMap.getInt("count")+1);
System.out.println(jobDataMap.getInt("count"));
}
}
main中
public static void main(String[] args) {
int count = 0 ;
JobDetail jobDetail = JobBuilder.newJob(MyJob.class)
.withIdentity("job1", "group1")
.usingJobData("job","jobDetail")
.usingJobData("count",count)
.build();
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "trigger1")
.usingJobData("trigger","trigger")
.usingJobData("count",count)
.startNow()
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1)
.repeatForever())
.build();
try {
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.scheduleJob(jobDetail,trigger);
scheduler.start();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
与springboot整合
QuartzJob 代码
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
public class QuartzJob extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
try {
Thread.sleep(2000);
//是否是同一个调度器
System.out.println(context.getScheduler().getSchedulerInstanceId());
//任务名
System.out.println("taskname="+context.getJobDetail().getKey().getName());
System.out.println("执行时间="+new Date());
} catch (Exception e) {
e.printStackTrace();
}
}
}
配置类
@Configuration
public class ScheduleConfig {
@Autowired
private DataSource dataSource;
@Bean
public Scheduler scheduler() throws IOException {
return schedulerFactoryBean().getScheduler();
}
@Bean
public SchedulerFactoryBean schedulerFactoryBean() throws IOException {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setSchedulerName("cluster_scheduler");
factory.setDataSource(dataSource);
factory.setApplicationContextSchedulerContextKey("application");
factory.setQuartzProperties(properties());
factory.setTaskExecutor(schedulerThreadPool());
factory.setStartupDelay(0);//延时多久执行 秒
return factory;
}
@Bean
public Properties properties() throws IOException {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setLocation(new ClassPathResource("/spring-quartz.properties"));
propertiesFactoryBean.afterPropertiesSet();
return propertiesFactoryBean.getObject();
}
@Bean //线程池
public Executor schedulerThreadPool(){
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//cpu核数 Runtime.getRuntime().availableProcessors()
executor.setCorePoolSize(Runtime.getRuntime().availableProcessors());
executor.setMaxPoolSize(Runtime.getRuntime().availableProcessors()+1);
//阻塞队列的个数
// executor.setQueueCapacity(Runtime.getRuntime().availableProcessors());
//IO密集型 CPU核心数/(1-阻塞系数)
return executor;
}
}
监听器类
@Component
public class StartApplicationListener implements ApplicationListener<ContextRefreshedEvent> {
@Autowired
private Scheduler scheduler;
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
try {
//触发器
TriggerKey triggerKey = TriggerKey.triggerKey("trigger1","group1");
Trigger trigger = scheduler.getTrigger(triggerKey);
if(trigger == null){
trigger = TriggerBuilder.newTrigger()
.withIdentity(triggerKey)
//cron 表达式 秒 分 时 日期 月份 周
.withSchedule(CronScheduleBuilder.cronSchedule("0/10 * * * * ?"))
.startNow()
.build();
JobDetail jobDetail = JobBuilder.newJob(QuartzJob.class)
.withIdentity("job1","group1")
.build();
scheduler.scheduleJob(jobDetail,trigger);
}
TriggerKey triggerKey2 = TriggerKey.triggerKey("trigger2","group2");
Trigger trigger2 = scheduler.getTrigger(triggerKey2);
if(trigger2 == null) {
trigger2 = TriggerBuilder.newTrigger()
.withIdentity(triggerKey2)
.withSchedule(CronScheduleBuilder.cronSchedule("0/10 * * * * ?"))
.startNow()
.build();
JobDetail jobDetail2 = JobBuilder.newJob(QuartzJob.class)
.withIdentity("job2", "group2")
.build();
scheduler.scheduleJob(jobDetail2, trigger2);
}
scheduler.start();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
yaml
server.context-path=/quartz-cluster2
#端口号
server.port=8082
# 数据源配置
spring.datasource.url=jdbc:mysql://localhost:3306/tuling?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.max-active=1000
spring.datasource.max-idle=20
spring.datasource.min-idle=5
spring.datasource.initial-size=10
spring-quartz.properties
#============================================================================
# 配置JobStore
#============================================================================
# JobDataMaps是否都为String类型,默认false
org.quartz.jobStore.useProperties=false
# 表的前缀,默认QRTZ_
org.quartz.jobStore.tablePrefix = QRTZ_
# 是否加入集群
org.quartz.jobStore.isClustered = true
# 调度实例失效的检查时间间隔 ms
org.quartz.jobStore.clusterCheckinInterval = 5000
# 当设置为“true”时,此属性告诉Quartz 在非托管JDBC连接上调用setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED)。
org.quartz.jobStore.txIsolationLevelReadCommitted = true
# 数据保存方式为数据库持久化
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
# 数据库代理类,一般org.quartz.impl.jdbcjobstore.StdJDBCDelegate可以满足大部分数据库
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#============================================================================
# Scheduler 调度器属性配置
#============================================================================
# 调度标识名 集群中每一个实例都必须使用相同的名称
org.quartz.scheduler.instanceName = ClusterQuartz
# ID设置为自动获取 每一个必须不同
org.quartz.scheduler.instanceId= AUTO
#============================================================================
# 配置ThreadPool
#============================================================================
# 线程池的实现类(一般使用SimpleThreadPool即可满足几乎所有用户的需求)
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
# 指定线程数,一般设置为1-100直接的整数,根据系统资源配置
org.quartz.threadPool.threadCount = 5
# 设置线程的优先级(可以是Thread.MIN_PRIORITY(即1)和Thread.MAX_PRIORITY(这是10)之间的任何int 。默认值为Thread.NORM_PRIORITY(5)。)
org.quartz.threadPool.threadPriority = 5