package com.xxl.job.admin.core.schedule;
import com.xxl.job.admin.core.jobbean.RemoteHttpJobBean;
import com.xxl.job.admin.core.model.XxlJobInfo;
import com.xxl.job.admin.core.thread.JobFailMonitorHelper;
import com.xxl.job.admin.core.thread.JobRegistryMonitorHelper;
import com.xxl.job.admin.core.util.I18nUtil;
import com.xxl.job.admin.dao.XxlJobGroupDao;
import com.xxl.job.admin.dao.XxlJobInfoDao;
import com.xxl.job.admin.dao.XxlJobLogDao;
import com.xxl.job.admin.dao.XxlJobRegistryDao;
import com.xxl.job.core.biz.AdminBiz;
import com.xxl.job.core.biz.ExecutorBiz;
import com.xxl.job.core.enums.ExecutorBlockStrategyEnum;
import com.xxl.job.core.rpc.netcom.NetComClientProxy;
import com.xxl.job.core.rpc.netcom.NetComServerFactory;
import org.quartz.*;
import org.quartz.Trigger.TriggerState;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.Assert;
import java.util.Date;
import java.util.HashSet;
import java.util.concurrent.ConcurrentHashMap;
/**
* base quartz scheduler util
* @author xuxueli 2015-12-19 16:13:53
*/
public final class XxlJobDynamicScheduler implements ApplicationContextAware {
private static final Logger logger = LoggerFactory.getLogger(XxlJobDynamicScheduler.class);
// ---------------------- param ----------------------
// scheduler
private static Scheduler scheduler;
public void setScheduler(Scheduler scheduler) {
XxlJobDynamicScheduler.scheduler = scheduler;
}
// accessToken
private static String accessToken;
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
// dao
public static XxlJobLogDao xxlJobLogDao;
public static XxlJobInfoDao xxlJobInfoDao;
public static XxlJobRegistryDao xxlJobRegistryDao;
public static XxlJobGroupDao xxlJobGroupDao;
public static AdminBiz adminBiz;
// ---------------------- applicationContext ----------------------
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
XxlJobDynamicScheduler.xxlJobLogDao = applicationContext.getBean(XxlJobLogDao.class);
XxlJobDynamicScheduler.xxlJobInfoDao = applicationContext.getBean(XxlJobInfoDao.class);
XxlJobDynamicScheduler.xxlJobRegistryDao = applicationContext.getBean(XxlJobRegistryDao.class);
XxlJobDynamicScheduler.xxlJobGroupDao = applicationContext.getBean(XxlJobGroupDao.class);
XxlJobDynamicScheduler.adminBiz = applicationContext.getBean(AdminBiz.class);
}
// ---------------------- init + destroy ----------------------
public void init() throws Exception {
// admin registry monitor run
JobRegistryMonitorHelper.getInstance().start();
// admin monitor run
JobFailMonitorHelper.getInstance().start();
// admin-server(spring-mvc)
NetComServerFactory.putService(AdminBiz.class, XxlJobDynamicScheduler.adminBiz);
NetComServerFactory.setAccessToken(accessToken);
// init i18n
initI18n();
// valid
Assert.notNull(scheduler, "quartz scheduler is null");
logger.info(">>>>>>>>> init xxl-job admin success.");
}
private void initI18n(){
for (ExecutorBlockStrategyEnum item:ExecutorBlockStrategyEnum.values()) {
item.setTitle(I18nUtil.getString("jobconf_block_".concat(item.name())));
}
}
public void destroy(){
// admin registry stop
JobRegistryMonitorHelper.getInstance().toStop();
// admin monitor stop
JobFailMonitorHelper.getInstance().toStop();
}
// ---------------------- executor-client ----------------------
private static ConcurrentHashMap<String, ExecutorBiz> executorBizRepository = new ConcurrentHashMap<String, ExecutorBiz>();
public static ExecutorBiz getExecutorBiz(String address) throws Exception {
// valid
if (address==null || address.trim().length()==0) {
return null;
}
// load-cache
address = address.trim();
ExecutorBiz executorBiz = executorBizRepository.get(address);
if (executorBiz != null) {
return executorBiz;
}
// set-cache
executorBiz = (ExecutorBiz) new NetComClientProxy(ExecutorBiz.class, address, accessToken).getObject();
executorBizRepository.put(address, executorBiz);
return executorBiz;
}
// ---------------------- schedule util ----------------------
/**
* fill job info
*
* @param jobInfo
*/
public static void fillJobInfo(XxlJobInfo jobInfo) {
// TriggerKey : name + group
String group = String.valueOf(jobInfo.getJobGroup());
String name = String.valueOf(jobInfo.getId());
TriggerKey triggerKey = TriggerKey.triggerKey(name, group);
try {
Trigger trigger = scheduler.getTrigger(triggerKey);
TriggerState triggerState = scheduler.getTriggerState(triggerKey);
// parse params
if (trigger!=null && trigger instanceof CronTriggerImpl) {
String cronExpression = ((CronTriggerImpl) trigger).getCronExpression();
jobInfo.setJobCron(cronExpression);
}
//JobKey jobKey = new JobKey(jobInfo.getJobName(), String.valueOf(jobInfo.getJobGroup()));
//JobDetail jobDetail = scheduler.getJobDetail(jobKey);
//String jobClass = jobDetail.getJobClass().getName();
if (triggerState!=null) {
jobInfo.setJobStatus(triggerState.name());
}
} catch (SchedulerException e) {
logger.error(e.getMessage(), e);
}
}
/**
* check if exists
*
* @param jobName
* @param jobGroup
* @return
* @throws SchedulerException
*/
public static boolean checkExists(String jobName, String jobGroup) throws SchedulerException{
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
return scheduler.checkExists(triggerKey);
}
/**
* addJob
*
* @param jobName
* @param jobGroup
* @param cronExpression
* @return
* @throws SchedulerException
*/
public static boolean addJob(String jobName, String jobGroup, String cronExpression) throws SchedulerException {
// TriggerKey : name + group
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
JobKey jobKey = new JobKey(jobName, jobGroup);
// TriggerKey valid if_exists
if (checkExists(jobName, jobGroup)) {
logger.info(">>>>>>>>> addJob fail, job already exist, jobGroup:{}, jobName:{}", jobGroup, jobName);
return false;
}
// CronTrigger : TriggerKey + cronExpression // withMisfireHandlingInstructionDoNothing 忽略掉调度终止过程中忽略的调度
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();
CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build();
// JobDetail : jobClass
Class<? extends Job> jobClass_ = RemoteHttpJobBean.class; // Class.forName(jobInfo.getJobClass());
JobDetail jobDetail = JobBuilder.newJob(jobClass_).withIdentity(jobKey).build();
/*if (jobInfo.getJobData()!=null) {
JobDataMap jobDataMap = jobDetail.getJobDataMap();
jobDataMap.putAll(JacksonUtil.readValue(jobInfo.getJobData(), Map.class));
// JobExecutionContext context.getMergedJobDataMap().get("mailGuid");
}*/
// schedule : jobDetail + cronTrigger
Date date = scheduler.scheduleJob(jobDetail, cronTrigger);
logger.info(">>>>>>>>>>> addJob success, jobDetail:{}, cronTrigger:{}, date:{}", jobDetail, cronTrigger, date);
return true;
}
/**
* rescheduleJob
*
* @param jobGroup
* @param jobName
* @param cronExpression
* @return
* @throws SchedulerException
*/
public static boolean rescheduleJob(String jobGroup, String jobName, String cronExpression) throws SchedulerException {
// TriggerKey valid if_exists
if (!checkExists(jobName, jobGroup)) {
logger.info(">>>>>>>>>>> rescheduleJob fail, job not exists, JobGroup:{}, JobName:{}", jobGroup, jobName);
return false;
}
// TriggerKey : name + group
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
CronTrigger oldTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
if (oldTrigger != null) {
// avoid repeat
String oldCron = oldTrigger.getCronExpression();
if (oldCron.equals(cronExpression)){
return true;
}
// CronTrigger : TriggerKey + cronExpression
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();
oldTrigger = oldTrigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build();
// rescheduleJob
scheduler.rescheduleJob(triggerKey, oldTrigger);
} else {
// CronTrigger : TriggerKey + cronExpression
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();
CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build();
// JobDetail-JobDataMap fresh
JobKey jobKey = new JobKey(jobName, jobGroup);
JobDetail jobDetail = scheduler.getJobDetail(jobKey);
/*JobDataMap jobDataMap = jobDetail.getJobDataMap();
jobDataMap.clear();
jobDataMap.putAll(JacksonUtil.readValue(jobInfo.getJobData(), Map.class));*/
// Trigger fresh
HashSet<Trigger> triggerSet = new HashSet<Trigger>();
triggerSet.add(cronTrigger);
scheduler.scheduleJob(jobDetail, triggerSet, true);
}
logger.info(">>>>>>>>>>> resumeJob success, JobGroup:{}, JobName:{}", jobGroup, jobName);
return true;
}
/**
* unscheduleJob
*
* @param jobName
* @param jobGroup
* @return
* @throws SchedulerException
*/
public static boolean removeJob(String jobName, String jobGroup) throws SchedulerException {
// TriggerKey : name + group
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
boolean result = false;
if (checkExists(jobName, jobGroup)) {
result = scheduler.unscheduleJob(triggerKey);
logger.info(">>>>>>>>>>> removeJob, triggerKey:{}, result [{}]", triggerKey, result);
}
return true;
}
/**
* pause
*
* @param jobName
* @param jobGroup
* @return
* @throws SchedulerException
*/
public static boolean pauseJob(String jobName, String jobGroup) throws SchedulerException {
// TriggerKey : name + group
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
boolean result = false;
if (checkExists(jobName, jobGroup)) {
scheduler.pauseTrigger(triggerKey);
result = true;
logger.info(">>>>>>>>>>> pauseJob success, triggerKey:{}", triggerKey);
} else {
logger.info(">>>>>>>>>>> pauseJob fail, triggerKey:{}", triggerKey);
}
return result;
}
/**
* resume
*
* @param jobName
* @param jobGroup
* @return
* @throws SchedulerException
*/
public static boolean resumeJob(String jobName, String jobGroup) throws SchedulerException {
// TriggerKey : name + group
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
boolean result = false;
if (checkExists(jobName, jobGroup)) {
scheduler.resumeTrigger(triggerKey);
result = true;
logger.info(">>>>>>>>>>> resumeJob success, triggerKey:{}", triggerKey);
} else {
logger.info(">>>>>>>>>>> resumeJob fail, triggerKey:{}", triggerKey);
}
return result;
}
/**
* run
*
* @param jobName
* @param jobGroup
* @return
* @throws SchedulerException
*/
public static boolean triggerJob(String jobName, String jobGroup) throws SchedulerException {
// TriggerKey : name + group
JobKey jobKey = new JobKey(jobName, jobGroup);
boolean result = false;
if (checkExists(jobName, jobGroup)) {
scheduler.triggerJob(jobKey);
result = true;
logger.info(">>>>>>>>>>> runJob success, jobKey:{}", jobKey);
} else {
logger.info(">>>>>>>>>>> runJob fail, jobKey:{}", jobKey);
}
return result;
}
/**
* finaAllJobList
*
* @return
*//*
@Deprecated
public static List<Map<String, Object>> finaAllJobList(){
List<Map<String, Object>> jobList = new ArrayList<Map<String,Object>>();
try {
if (scheduler.getJobGroupNames()==null || scheduler.getJobGroupNames().size()==0) {
return null;
}
String groupName = scheduler.getJobGroupNames().get(0);
Set<JobKey> jobKeys = scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName));
if (jobKeys!=null && jobKeys.size()>0) {
for (JobKey jobKey : jobKeys) {
TriggerKey triggerKey = TriggerKey.triggerKey(jobKey.getName(), Scheduler.DEFAULT_GROUP);
Trigger trigger = scheduler.getTrigger(triggerKey);
JobDetail jobDetail = scheduler.getJobDetail(jobKey);
TriggerState triggerState = scheduler.getTriggerState(triggerKey);
Map<String, Object> jobMap = new HashMap<String, Object>();
jobMap.put("TriggerKey", triggerKey);
jobMap.put("Trigger", trigger);
jobMap.put("JobDetail", jobDetail);
jobMap.put("TriggerState", triggerState);
jobList.add(jobMap);
}
}
} catch (SchedulerException e) {
logger.error(e.getMessage(), e);
return null;
}
return jobList;
}*/
}
Cron+Trigger+Quartz 任务 启动 暂停 恢复 修改 实例
最新推荐文章于 2024-04-14 14:03:54 发布