parent
08950b0b6c
commit
328f98a252
@ -1,2 +1,5 @@
|
||||
# xxl-job
|
||||
任务调度框架xxl-job
|
||||
# 任务调度框架xxl-job
|
||||
|
||||
Scheduler
|
||||
Trigger
|
||||
JobDetail
|
||||
|
@ -0,0 +1,90 @@
|
||||
package com.xxl.quartz;
|
||||
|
||||
import org.quartz.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public final class DynamicSchedulerUtil implements InitializingBean {
|
||||
private static final Logger logger = LoggerFactory.getLogger(DynamicSchedulerUtil.class);
|
||||
|
||||
// Scheduler
|
||||
private static Scheduler scheduler;
|
||||
public static void setScheduler(Scheduler scheduler) {
|
||||
DynamicSchedulerUtil.scheduler = scheduler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(scheduler, "quartz scheduler is null");
|
||||
logger.info(">>>>>>>>> init quartz scheduler success.[{}]", scheduler);
|
||||
}
|
||||
|
||||
// Add 新增
|
||||
public static boolean addJob(JobModel job) throws SchedulerException {
|
||||
final TriggerKey triggerKey = job.getTriggerKey();
|
||||
if (scheduler.checkExists(triggerKey)) {
|
||||
final Trigger trigger = scheduler.getTrigger(triggerKey);
|
||||
logger.info(">>>>>>>>> Already exist trigger [" + trigger + "] by key [" + triggerKey + "] in Scheduler");
|
||||
return false;
|
||||
}
|
||||
|
||||
final CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
|
||||
final CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(triggerKey)
|
||||
.withSchedule(cronScheduleBuilder)
|
||||
.build();
|
||||
|
||||
final JobDetail jobDetail = job.getJobDetail();
|
||||
final Date date = scheduler.scheduleJob(jobDetail, cronTrigger);
|
||||
|
||||
logger.debug("Register DynamicJob {} on [{}]", job, date);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Pause 暂停-指定Job
|
||||
public static boolean pauseJob(JobModel existJob) throws SchedulerException {
|
||||
final TriggerKey triggerKey = existJob.getTriggerKey();
|
||||
boolean result = false;
|
||||
if (scheduler.checkExists(triggerKey)) {
|
||||
scheduler.pauseTrigger(triggerKey);
|
||||
result = true;
|
||||
logger.debug("Pause exist DynamicJob {}, triggerKey [{}] successful", existJob, triggerKey);
|
||||
} else {
|
||||
logger.debug("Failed pause exist DynamicJob {}, because not fount triggerKey [{}]", existJob, triggerKey);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Resume 重启-指定Job
|
||||
public static boolean resumeJob(JobModel existJob) throws SchedulerException {
|
||||
final TriggerKey triggerKey = existJob.getTriggerKey();
|
||||
boolean result = false;
|
||||
if (scheduler.checkExists(triggerKey)) {
|
||||
final CronTrigger newTrigger = existJob.cronTrigger();
|
||||
final Date date = scheduler.rescheduleJob(triggerKey, newTrigger);
|
||||
|
||||
result = true;
|
||||
logger.debug("Resume exist DynamicJob {}, triggerKey [{}] on [{}] successful", existJob, triggerKey, date);
|
||||
} else {
|
||||
logger.debug("Failed resume exist DynamicJob {}, because not fount triggerKey [{}]", existJob, triggerKey);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Remove exists job 移除-指定Job
|
||||
public static boolean removeJob(JobModel existJob) throws SchedulerException {
|
||||
final TriggerKey triggerKey = existJob.getTriggerKey();
|
||||
boolean result = false;
|
||||
if (scheduler.checkExists(triggerKey)) {
|
||||
result = scheduler.unscheduleJob(triggerKey);
|
||||
}
|
||||
|
||||
logger.debug("Remove DynamicJob {} result [{}]", existJob, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
package com.xxl.quartz;
|
||||
|
||||
import org.quartz.CronScheduleBuilder;
|
||||
import org.quartz.CronTrigger;
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobBuilder;
|
||||
import org.quartz.JobDataMap;
|
||||
import org.quartz.JobDetail;
|
||||
import org.quartz.Scheduler;
|
||||
import org.quartz.TriggerBuilder;
|
||||
import org.quartz.TriggerKey;
|
||||
|
||||
/**
|
||||
* 任务model
|
||||
* @author xuxueli 2015-12-1 16:01:19
|
||||
*/
|
||||
public class JobModel {
|
||||
|
||||
// param
|
||||
private String group;
|
||||
private String name;
|
||||
private String cronExpression;
|
||||
private Class<? extends Job> jobClass;
|
||||
|
||||
public JobModel(String name, String cronExpression, Class<? extends Job> jobClass) {
|
||||
this.group = Scheduler.DEFAULT_GROUP;
|
||||
this.name = name;
|
||||
this.cronExpression = cronExpression;
|
||||
this.jobClass = jobClass;
|
||||
}
|
||||
|
||||
public String getGroup() {
|
||||
return group;
|
||||
}
|
||||
public void setGroup(String group) {
|
||||
this.group = group;
|
||||
}
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public String getCronExpression() {
|
||||
return cronExpression;
|
||||
}
|
||||
public void setCronExpression(String cronExpression) {
|
||||
this.cronExpression = cronExpression;
|
||||
}
|
||||
public Class<? extends Job> getJobClass() {
|
||||
return jobClass;
|
||||
}
|
||||
public void setJobClass(Class<? extends Job> jobClass) {
|
||||
this.jobClass = jobClass;
|
||||
}
|
||||
|
||||
// TriggerKey
|
||||
public TriggerKey getTriggerKey() {
|
||||
return TriggerKey.triggerKey(this.name, this.group);
|
||||
}
|
||||
// JobDetail
|
||||
public JobDetail getJobDetail() {
|
||||
return JobBuilder.newJob(jobClass).withIdentity(this.name, this.group).build();
|
||||
}
|
||||
// JobDataMap.add
|
||||
public JobModel addJobData(String key, Object value) {
|
||||
JobDataMap jobDataMap = this.getJobDetail().getJobDataMap();
|
||||
jobDataMap.put(key, value);
|
||||
return this;
|
||||
}
|
||||
// CronTrigger
|
||||
public CronTrigger cronTrigger() {
|
||||
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(this.cronExpression);
|
||||
return TriggerBuilder.newTrigger().withIdentity(this.getTriggerKey()).withSchedule(cronScheduleBuilder).build();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.xxl.service.job;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.commons.lang.time.FastDateFormat;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.JobExecutionException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.scheduling.quartz.QuartzJobBean;
|
||||
|
||||
public class JobDetailDemo extends QuartzJobBean {
|
||||
private static Logger logger = LoggerFactory.getLogger(JobDetailDemo.class);
|
||||
|
||||
@Override
|
||||
protected void executeInternal(JobExecutionContext context)
|
||||
throws JobExecutionException {
|
||||
logger.info("全站静态化[DB] run at :{}", FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss").format(new Date()));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
# Default Properties file for use by StdSchedulerFactory
|
||||
# to create a Quartz Scheduler Instance, if a different
|
||||
# properties file is not explicitly specified.
|
||||
#
|
||||
|
||||
org.quartz.scheduler.instanceName: DefaultQuartzScheduler
|
||||
org.quartz.scheduler.rmi.export: false
|
||||
org.quartz.scheduler.rmi.proxy: false
|
||||
org.quartz.scheduler.wrapJobExecutionInUserTransaction: false
|
||||
|
||||
org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
|
||||
org.quartz.threadPool.threadCount: 10
|
||||
org.quartz.threadPool.threadPriority: 5
|
||||
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true
|
||||
|
||||
org.quartz.jobStore.misfireThreshold: 60000
|
||||
|
||||
#org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore
|
||||
|
||||
# for cluster
|
||||
org.quartz.scheduler.instanceId: AUTO
|
||||
org.quartz.jobStore.class: org.quartz.impl.jdbcjobstore.JobStoreTX
|
||||
org.quartz.jobStore.isClustered: true
|
||||
org.quartz.jobStore.clusterCheckinInterval: 1000
|
@ -0,0 +1,30 @@
|
||||
package quartz;
|
||||
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.quartz.SchedulerException;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.xxl.quartz.DynamicSchedulerUtil;
|
||||
import com.xxl.quartz.JobModel;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations = "classpath*:applicationcontext-*.xml")
|
||||
public class JunitTest {
|
||||
|
||||
@Test
|
||||
public void addJob() throws SchedulerException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InterruptedException {
|
||||
boolean ret = DynamicSchedulerUtil.addJob(new JobModel("Jost-job", "0/1 * * * * ?", TestDynamicJob.class));
|
||||
System.out.println(ret);
|
||||
TimeUnit.SECONDS.sleep(30);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package quartz;
|
||||
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.JobExecutionException;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class TestDynamicJob implements Job {
|
||||
|
||||
|
||||
@Override
|
||||
public void execute(JobExecutionContext context) throws JobExecutionException {
|
||||
final Object mailGuid = context.getMergedJobDataMap().get("mailGuid");
|
||||
System.out.println("[Dynamic-Job] It is " + new Date() + " now, mailGuid=" + mailGuid);
|
||||
}
|
||||
}
|
Loading…
Reference in new issue