• Quartz学习笔记(七) quartz与spring实现任务动态管理面板


    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;
        }
    }
    
  • 相关阅读:
    解题报告:POJ1852 Ants
    解题报告:POJ2573 Bridge(分析建模)
    POJ 3321 Apple Tree(树状数组模板)
    PAT1139 First Contact
    POJ3259 SPFA判定负环
    HDOJ2586 最近公共祖先模板
    树的直径与最近公共祖先
    字符数组_随机存储
    青鸟资料下载
    软件测试(4)_LoadRunner使用
  • 原文地址:https://www.cnblogs.com/zouhao510/p/5313612.html
Copyright © 2020-2023  润新知