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; } }