Quartz学习笔记(七) quartz与spring实现任务动态管理面板
任务面板CRUD操作接口:
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.quartz.*;
import org.quartz.impl.StdScheduler;
import org.quartz.impl.matchers.GroupMatcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* [简短描述该类的功能]
*
*/
@Service
public class JobManager {
private static final Logger log = LoggerFactory.getLogger(JobManager.class);
@Resource
private StdScheduler scheduler;
/**
* 获取计划中的任务列表
* @return
*/
public List<ScheduleJob> getPlanJobList(){
List<ScheduleJob> jobList = new ArrayList<>();
try {
GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
Set<JobKey> jobKeySet = scheduler.getJobKeys(matcher);
for (JobKey jobKey : jobKeySet){
List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
for (Trigger trigger : triggers){
ScheduleJob scheduleJob = new ScheduleJob();
this.wrapScheduleJob(scheduleJob,scheduler,jobKey,trigger);
jobList.add(scheduleJob);
}
}
} catch (SchedulerException e) {
log.error("获取计划任务列表失败: {}", ExceptionUtils.getStackTrace(e));
throw new RuntimeException("获取计划任务列表失败",e);
}
return jobList;
}
/**
* 获取正在运行的任务列表
* @return
*/
public List<ScheduleJob> getRunningJobList(){
List<JobExecutionContext> executingJobList = scheduler.getCurrentlyExecutingJobs();
List<ScheduleJob> jobList = new ArrayList<>(executingJobList.size());
for(JobExecutionContext executingJob : executingJobList){
ScheduleJob scheduleJob = new ScheduleJob();
JobDetail jobDetail = executingJob.getJobDetail();
JobKey jobKey = jobDetail.getKey();
Trigger trigger = executingJob.getTrigger();
this.wrapScheduleJob(scheduleJob,scheduler,jobKey,trigger);
jobList.add(scheduleJob);
}
return jobList;
}
/**
* 封装ScheduleJob对象
* @param scheduleJob
* @param scheduler
* @param jobKey
* @param trigger
*/
private void wrapScheduleJob(ScheduleJob scheduleJob,Scheduler scheduler,JobKey jobKey,Trigger trigger){
try {
scheduleJob.setJobName(jobKey.getName());
scheduleJob.setJobGroup(jobKey.getGroup());
JobDetail jobDetail = scheduler.getJobDetail(jobKey);
ScheduleJob job = (ScheduleJob)jobDetail.getJobDataMap().get("scheduleJob");
scheduleJob.setDesc(job.getDesc());
Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
scheduleJob.setJobStatus(triggerState.name());
if(trigger instanceof CronTrigger){
CronTrigger cronTrigger = (CronTrigger)trigger;
String cronExpression = cronTrigger.getCronExpression();
scheduleJob.setCronExpression(cronExpression);
}
} catch (SchedulerException e) {
log.error("获取触发器状态失败: {}", ExceptionUtils.getStackTrace(e));
throw new RuntimeException(e);
}
}
/**
* 新增任务
* @param scheduleJob
*/
public void addJob(ScheduleJob scheduleJob){
try {
TriggerKey triggerKey = TriggerKey.triggerKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
if(trigger != null){
throw new BusinessException("添加任务失败,任务名称已重复");
}
JobDetail jobDetail = JobBuilder.newJob(QuartzJobFactory.class).withIdentity(scheduleJob.getJobName(),scheduleJob.getJobGroup()).build();
jobDetail.getJobDataMap().put("scheduleJob", scheduleJob);
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression());
trigger = TriggerBuilder.newTrigger().withIdentity(scheduleJob.getJobName(), scheduleJob.getJobGroup()).withSchedule(cronScheduleBuilder).build();
scheduler.scheduleJob(jobDetail, trigger);
} catch (Exception e) {
log.error("添加任务失败: {}", ExceptionUtils.getStackTrace(e));
throw new RuntimeException("添加任务失败",e);
}
}
/**
* 暂停任务
* @param scheduleJob
*/
public void pauseJob(ScheduleJob scheduleJob){
JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
try {
scheduler.pauseJob(jobKey);
} catch (SchedulerException e) {
log.error("暂停任务失败: {}", ExceptionUtils.getStackTrace(e));
throw new RuntimeException("暂停任务失败",e);
}
}
/**
* 恢复任务执行
* @param scheduleJob
*/
public void resumeJob(ScheduleJob scheduleJob){
JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
try {
scheduler.resumeJob(jobKey);
} catch (SchedulerException e) {
log.error("恢复任务失败: {}", ExceptionUtils.getStackTrace(e));
throw new RuntimeException("恢复任务失败",e);
}
}
/**
* 删除任务
* @param scheduleJob
*/
public void deleteJob(ScheduleJob scheduleJob){
JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
try {
scheduler.deleteJob(jobKey);
} catch (SchedulerException e) {
log.error("删除任务失败: {}", ExceptionUtils.getStackTrace(e));
throw new RuntimeException("删除任务失败",e);
}
}
/**
* 立即执行任务
* @param scheduleJob
*/
public void runJobOnce(ScheduleJob scheduleJob){
JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
try {
scheduler.triggerJob(jobKey);
} catch (Exception e) {
log.error("只运行一次任务失败: {}", ExceptionUtils.getStackTrace(e));
throw new RuntimeException("只运行一次任务失败",e);
}
}
/**
* 修改任务执行表达式
* @param scheduleJob
*/
public void updateJobCronExpression(ScheduleJob scheduleJob){
TriggerKey triggerKey = TriggerKey.triggerKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
try {
CronTrigger cronTrigger = (CronTrigger)scheduler.getTrigger(triggerKey);
//表达式调度构建器
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression());
//按新的cronExpression表达式重新构建trigger
cronTrigger = cronTrigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build();
//按新的trigger重新设置job执行
scheduler.rescheduleJob(triggerKey, cronTrigger);
} catch (SchedulerException e) {
log.error("修改任务执行表达式失败: {}", ExceptionUtils.getStackTrace(e));
throw new RuntimeException("修改任务执行表达式失败",e);
}
}
}
定时任务运行入口:
import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.UUID;
/**
* [定时任务运行工厂类]
*/
public class QuartzJobFactory implements Job {
private static final Logger log = LoggerFactory.getLogger(QuartzJobFactory.class);
public void execute(JobExecutionContext context) throws JobExecutionException {
ScheduleJob scheduleJob = (ScheduleJob) context.getMergedJobDataMap().get("scheduleJob");
String jobFullName = StringUtils.join(new String[]{scheduleJob.getJobGroup(),scheduleJob.getJobName()},".");
String lockKey = jobFullName + ".lock";
if(RedisUtil.acquireLock(lockKey, 1000)) {
log.info("任务{}成功获取锁",jobFullName);
String uid = UUID.randomUUID().toString();
PushMsg msg = new PushMsg();
msg.setInterfaceName("cn.gooday.scheduler.service.ISchedulerPullService");
msg.setReqUniId(uid);
msg.setMsgbody("msgbody");
msg.setSystemid("systemA");
PushInfo pushInfo = new PushInfo();
pushInfo.setTopic("jsh-mq-service-test-zj4");
pushInfo.setGoupName("jsh-mq-service-group-test-zj4");
pushInfo.setSystemid("systemA");
pushInfo.setReqUniId(uid);
ArrayList<PushMsg> list = new ArrayList<PushMsg>();
list.add(msg);
pushInfo.setMsg(list);
pushInfo.setIsOrderly("1");
String jsonStr = JSON.toJSONString(pushInfo);
LssMQPushService lssMQPushService = (LssMQPushService) SpringContextUtil.getBean("lssMQPushService");
String rtn = lssMQPushService.pushInfo(jsonStr);
log.info(rtn);
}
}
}
spring配置文件
<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="configLocation" value="classpath:quartz.properties" />
</bean>
quartz配置文件
org.quartz.scheduler.instanceName: MyScheduler org.quartz.scheduler.instanceId: AUTO #============================================================================ # ThreadPool #============================================================================ org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool org.quartz.threadPool.threadCount: 20 org.quartz.threadPool.threadPriority: 5 #============================================================================ # JobStore #============================================================================ org.quartz.jobStore.class: org.quartz.impl.jdbcjobstore.JobStoreTX #============================================================================ # Cluster #============================================================================ org.quartz.jobStore.isClustered: true org.quartz.jobStore.clusterCheckinInterval: 15000 org.quartz.jobStore.maxMisfiresToHandleAtATime: 1 org.quartz.jobStore.misfireThreshold: 120000 org.quartz.jobStore.tablePrefix: qrtz_ schedulerName:MyScheduler startupDelay: 30 applicationContextSchedulerContextKey: applicationContextKey overwriteExistingJobs : true autoStartup: true #============================================================================ # JDBC #============================================================================ org.quartz.jobStore.driverDelegateClass:org.quartz.impl.jdbcjobstore.StdJDBCDelegate org.quartz.jobStore.useProperties:false org.quartz.jobStore.dataSource:qzDS #org.quartz.dataSource.qzDS.connectionProvider.class:org.quartz.utils.PoolingConnectionProvider org.quartz.dataSource.qzDS.connectionProvider.class:cn.gooday.scheduler.common.druid.DruidConnectionProvider org.quartz.dataSource.qzDS.driver:com.mysql.jdbc.Driver org.quartz.dataSource.qzDS.URL:jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8 org.quartz.dataSource.qzDS.user:root org.quartz.dataSource.qzDS.password:root org.quartz.dataSource.qzDS.maxConnection:30 org.quartz.dataSource.qzDS.validationQuery: select 0
实体类(序列化)
import java.io.Serializable;
public class ScheduleJob implements Serializable{
private static final long serialVersionUID = 1L;
private String jobId;
private String jobName;
private String jobGroup;
private String jobStatus;
private String cronExpression;
private String interfaceName; //接口名称,用于MQ进行接口回调
private String desc;
public String getJobId() {
return jobId;
}
public void setJobId(String jobId) {
this.jobId = jobId;
}
public String getJobName() {
return jobName;
}
public void setJobName(String jobName) {
this.jobName = jobName;
}
public String getJobGroup() {
return jobGroup;
}
public void setJobGroup(String jobGroup) {
this.jobGroup = jobGroup;
}
public String getJobStatus() {
return jobStatus;
}
public void setJobStatus(String jobStatus) {
this.jobStatus = jobStatus;
}
public String getCronExpression() {
return cronExpression;
}
public void setCronExpression(String cronExpression) {
this.cronExpression = cronExpression;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String getInterfaceName() {
return interfaceName;
}
public void setInterfaceName(String interfaceName) {
this.interfaceName = interfaceName;
}
}