资讯专栏INFORMATION COLUMN

SpringCloud(第 010 篇)简单 Quartz-Cluster 支持集群分布式且支持动态

xiyang / 2171人阅读

摘要:通过再添加其他的元素可在中放置多个触发器。停止触发器重启触发器停止触发器移除触发器添加调度的任务类调度的任务。执行的张表入数据库添加启动类简单微服务,支持集群分布式,并支持动态修改任务的执行时间。

SpringCloud(第 010 篇)简单 Quartz-Cluster 微服务,支持集群分布式,并支持动态修改 Quartz 任务的 cronExpression 执行时间

-

一、大致介绍
1、根据上一章节的单台测试,本章节修改 Quartz 了支持分布式,因为这是更多的企业开发场景所需要的开发模式;
2、而且在定时任务执行的过程中,通过修改 Quartz 触发器表的 cronExpression 表达式值,从而达到动态修改定时任务的执行时间;

3、注意:配置文件中的 mysql 数据库链接配置大家就各自配置自己的哈;
二、实现步骤 2.1 添加 maven 引用包


    4.0.0

    springms-simple-quartz-cluster
    1.0-SNAPSHOT
    jar
    
    
        com.springms.cloud
        springms-spring-cloud
        1.0-SNAPSHOT
    
    
    
        
        
            org.springframework.boot
            spring-boot-starter-data-jpa
        

        
        
            org.springframework.boot
            spring-boot-starter-web
        

        
        
            mysql
            mysql-connector-java
        

        
        
            org.springframework.boot
            spring-boot-starter-jdbc
        
               
        
        
            org.quartz-scheduler
            quartz
            2.3.0
        
        
            org.quartz-scheduler
            quartz-jobs
            2.3.0
        
        
            org.springframework
            spring-context-support
        

        
        
            com.alibaba
            druid
            1.1.3
        
    


2.2 添加应用配置文件(springms-simple-quartz-cluster/src/main/resources/application.yml)
server:
  port: 8395
spring:
  application:
    name: springms-simple-quartz-cluster  #全部小写


#####################################################################################################
# mysql 属性配置
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://ip:port/hmilyylimh?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true
    username: username
    password: password
  jpa:
    hibernate:
      #ddl-auto: create #ddl-auto:设为create表示每次都重新建表
      ddl-auto: update #ddl-auto:设为update表示每次都不会重新建表
    show-sql: true
#####################################################################################################




#####################################################################################################
#########mysql######### 注释先不用这些属性
#spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
#spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true
#spring.datasource.username=test
#spring.datasource.password=test
#
#
#spring.datasource.initialSize=5
#spring.datasource.minIdle=5
#spring.datasource.maxActive=20
#spring.datasource.maxWait=60000
#
#
#spring.datasource.timeBetweenEvictionRunsMillis=3600000
#spring.datasource.minEvictableIdleTimeMillis=18000000
#
#
#spring.datasource.validationQuery=SELECT 1 FROM DUAL
#spring.datasource.testWhileIdle=true
#spring.datasource.testOnBorrow=true
#spring.datasource.testOnReturn=true
#spring.datasource.poolPreparedStatements=true
#spring.datasource.maxPoolPreparedStatementPerConnectionSize=20
#spring.datasource.filters=stat,wall,log4j
#spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
#####################################################################################################




#####################################################################################################
# 打印日志
logging:
  level:
    root: INFO
    org.hibernate: INFO
    org.hibernate.type.descriptor.sql.BasicBinder: TRACE
    org.hibernate.type.descriptor.sql.BasicExtractor: TRACE
    com.springms: DEBUG
#####################################################################################################
2.3 添加 quartz 配置文件(springms-simple-quartz-cluster/src/main/resources/quartz.properties)
org.quartz.scheduler.instanceName = quartzScheduler  
org.quartz.scheduler.instanceId = AUTO  


org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX  
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.tablePrefix = QRTZ_  
org.quartz.jobStore.isClustered = true  
org.quartz.jobStore.useProperties = false
org.quartz.jobStore.clusterCheckinInterval = 20000    


org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool  
org.quartz.threadPool.threadCount = 10  
org.quartz.threadPool.threadPriority = 5  
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
2.4 添加 quartz 任务配置文件(springms-simple-quartz-cluster/src/main/resources/quartz.xml)




    
        
        
        
        
            
                com.springms.cloud.job.DetailQuartzJobBean
            
        
        
            
                
                
                
                
            
        
    

    
        
            
        
        
            0/10 * * * * ?
        
    

    
        
        
        
        
        
            
                
            
        
        
        
        
    

2.5 添加定时任务作业类(springms-simple-quartz-cluster/src/main/java/com/springms/cloud/job/DetailQuartzJobBean.java)
package com.springms.cloud.job;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.quartz.QuartzJobBean;

import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 定时任务作业类。
 *
 * @author hmilyylimh
 *
 * @version 0.0.1
 *
 * @date 17/9/18
 *
 */
public class DetailQuartzJobBean extends QuartzJobBean {

    private String targetObject;
    private String targetMethod;
    private ApplicationContext ctx;

    // 配置中设定了
    // ① targetMethod: 指定需要定时执行scheduleInfoAction中的simpleJobTest()方法
    // ② concurrent:对于相同的JobDetail,当指定多个Trigger时, 很可能第一个job完成之前,
    // 第二个job就开始了。指定concurrent设为false,多个job不会并发运行,第二个job将不会在第一个job完成之前开始。
    // ③ cronExpression:0/10 * * * * ?表示每10秒执行一次,具体可参考附表。
    // ④ triggers:通过再添加其他的ref元素可在list中放置多个触发器。 scheduleInfoAction中的simpleJobTest()方法
    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        try {
            Object otargetObject = ctx.getBean(targetObject);
            Method m = null;

            System.out.println(targetObject + " - " + targetMethod + " - " + ((new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS")).format(new Date())));
            try {
                m = otargetObject.getClass().getMethod(targetMethod, new Class[] { JobExecutionContext.class });
                m.invoke(otargetObject, new Object[] { context });
            } catch (SecurityException e) {
                // Logger.error(e);
                System.out.println(e.getMessage());
            } catch (NoSuchMethodException e) {
                // Logger.error(e);
                System.out.println(e.getMessage());
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
            throw new JobExecutionException(e);
        }
    }

    public void setApplicationContext(ApplicationContext applicationContext) {
        this.ctx = applicationContext;
    }

    public void setTargetObject(String targetObject) {
        this.targetObject = targetObject;
    }

    public void setTargetMethod(String targetMethod) {
        this.targetMethod = targetMethod;
    }
}
2.6 添加调度服务接口(springms-simple-quartz-cluster/src/main/java/com/springms/cloud/service/ISchedulerService.java)
package com.springms.cloud.service;

import java.util.Date;
  
import org.quartz.CronExpression;  
  
/**
 * 调度服务接口。
 *
 * @author hmilyylimh
 *
 * @version 0.0.1
 *
 * @date 2017/9/18
 *
 */
public interface ISchedulerService {
    
    /** 
     * 根据 Quartz Cron Expression 调试任务 
     *  
     * @param cronExpression 
     *            Quartz Cron 表达式,如 "0/10 * * ? * * *"等 
     */  
    void schedule(String cronExpression);  
  
    /** 
     * 根据 Quartz Cron Expression 调试任务 
     *  
     * @param name 
     *            Quartz CronTrigger名称 
     * @param cronExpression 
     *            Quartz Cron 表达式,如 "0/10 * * ? * * *"等 
     */  
    void schedule(String name, String cronExpression);  
  
    /** 
     * 根据 Quartz Cron Expression 调试任务 
     *  
     * @param name 
     *            Quartz CronTrigger名称 
     * @param group 
     *            Quartz CronTrigger组 
     * @param cronExpression 
     *            Quartz Cron 表达式,如 "0/10 * * ? * * *"等 
     */  
    void schedule(String name, String group, String cronExpression);  
  
    /** 
     * 根据 Quartz Cron Expression 调试任务 
     *  
     * @param cronExpression 
     *            Quartz CronExpression 
     */  
    void schedule(CronExpression cronExpression);  
  
    /** 
     * 根据 Quartz Cron Expression 调试任务 
     *  
     * @param name 
     *            Quartz CronTrigger名称 
     * @param cronExpression 
     *            Quartz CronExpression 
     */  
    void schedule(String name, CronExpression cronExpression);  
  
    /** 
     * 根据 Quartz Cron Expression 调试任务 
     *  
     * @param name 
     *            Quartz CronTrigger名称 
     * @param group 
     *            Quartz CronTrigger组 
     * @param cronExpression 
     *            Quartz CronExpression 
     */  
    void schedule(String name, String group, CronExpression cronExpression);  
  
    /** 
     * 在startTime时执行调试一次 
     *  
     * @param startTime 
     *            调度开始时间 
     */  
    void schedule(Date startTime);  
  
    void schedule(Date startTime, String group);  
  
    /** 
     * 在startTime时执行调试一次 
     *  
     * @param name 
     *            Quartz SimpleTrigger 名称 
     * @param startTime 
     *            调度开始时间 
     */  
    void schedule(String name, Date startTime);  
  
    void schedule(String name, Date startTime, String group);  
  
    /** 
     * 在startTime时执行调试,endTime结束执行调度 
     *  
     * @param startTime 
     *            调度开始时间 
     * @param endTime 
     *            调度结束时间 
     */  
    void schedule(Date startTime, Date endTime);  
  
    void schedule(Date startTime, Date endTime, String group);  
  
    /** 
     * 在startTime时执行调试,endTime结束执行调度 
     *  
     * @param name 
     *            Quartz SimpleTrigger 名称 
     * @param startTime 
     *            调度开始时间 
     * @param endTime 
     *            调度结束时间 
     */  
    void schedule(String name, Date startTime, Date endTime);  
  
    void schedule(String name, Date startTime, Date endTime, String group);  
  
    /** 
     * 在startTime时执行调试,endTime结束执行调度,重复执行repeatCount次 
     *  
     * @param startTime 
     *            调度开始时间 
     * @param repeatCount 
     *            重复执行次数 
     */  
    void schedule(Date startTime, int repeatCount);  
  
    /** 
     * 在startTime时执行调试,endTime结束执行调度,重复执行repeatCount次 
     *  
     * @param startTime 
     *            调度开始时间 
     * @param endTime 
     *            调度结束时间 
     * @param repeatCount 
     *            重复执行次数 
     */  
    void schedule(Date startTime, Date endTime, int repeatCount);  
  
    void schedule(Date startTime, Date endTime, int repeatCount, String group);  
  
    /** 
     * 在startTime时执行调试,endTime结束执行调度,重复执行repeatCount次 
     *  
     * @param name 
     *            Quartz SimpleTrigger 名称 
     * @param startTime 
     *            调度开始时间 
     * @param endTime 
     *            调度结束时间 
     * @param repeatCount 
     *            重复执行次数 
     */  
    void schedule(String name, Date startTime, Date endTime, int repeatCount);  
  
    void schedule(String name, Date startTime, Date endTime, int repeatCount, String group);  
  
    /** 
     * 在startTime时执行调试,endTime结束执行调度,重复执行repeatCount次,每隔repeatInterval秒执行一次 
     *  
     * @param startTime 
     *            调度开始时间 
     *  
     * @param repeatCount 
     *            重复执行次数 
     * @param repeatInterval 
     *            执行时间隔间 
     */  
    void schedule(Date startTime, int repeatCount, long repeatInterval);  
  
    /** 
     * 在startTime时执行调试,endTime结束执行调度,重复执行repeatCount次,每隔repeatInterval秒执行一次 
     *  
     * @param startTime 
     *            调度开始时间 
     * @param endTime 
     *            调度结束时间 
     * @param repeatCount 
     *            重复执行次数 
     * @param repeatInterval 
     *            执行时间隔间 
     */  
    void schedule(Date startTime, Date endTime, int repeatCount, long repeatInterval);  
  
    void schedule(Date startTime, Date endTime, int repeatCount, long repeatInterval, String group);  
  
    /** 
     * 在startTime时执行调试,endTime结束执行调度,重复执行repeatCount次,每隔repeatInterval秒执行一次 
     *  
     * @param name 
     *            Quartz SimpleTrigger 名称 
     * @param startTime 
     *            调度开始时间 
     * @param endTime 
     *            调度结束时间 
     * @param repeatCount 
     *            重复执行次数 
     * @param repeatInterval 
     *            执行时间隔间 
     */  
    void schedule(String name, Date startTime, Date endTime, int repeatCount, long repeatInterval);  
  
    void schedule(String name, Date startTime, Date endTime, int repeatCount, long repeatInterval, String group);  
  
    /** 
     * 暂停触发器 
     *  
     * @param triggerName 
     *            触发器名称 
     */  
    void pauseTrigger(String triggerName);  
  
    /** 
     * 暂停触发器 
     *  
     * @param triggerName 
     *            触发器名称 
     * @param group 
     *            触发器组 
     */  
    void pauseTrigger(String triggerName, String group);  
  
    /** 
     * 恢复触发器 
     *  
     * @param triggerName 
     *            触发器名称 
     */  
    void resumeTrigger(String triggerName);  
  
    /** 
     * 恢复触发器 
     *  
     * @param triggerName 
     *            触发器名称 
     * @param group 
     *            触发器组 
     */  
    void resumeTrigger(String triggerName, String group);  
  
    /** 
     * 删除触发器 
     *  
     * @param triggerName 
     *            触发器名称 
     * @return 
     */  
    boolean removeTrigdger(String triggerName);  
  
    /** 
     * 删除触发器 
     *  
     * @param triggerName 
     *            触发器名称 
     * @param group 
     *            触发器组 
     * @return 
     */  
    boolean removeTrigdger(String triggerName, String group);  
}  
2.7 添加调度服务实现类(springms-simple-quartz-cluster/src/main/java/com/springms/cloud/service/impl/SchedulerServiceImpl.java)
package com.springms.cloud.service.impl;

import java.text.ParseException;
import java.util.Date;  
import java.util.UUID;

import com.springms.cloud.service.ISchedulerService;
import org.quartz.CronExpression;
import org.quartz.JobDetail;  
import org.quartz.Scheduler;  
import org.quartz.SchedulerException;  
import org.quartz.TriggerKey;  
import org.quartz.impl.triggers.CronTriggerImpl;  
import org.quartz.impl.triggers.SimpleTriggerImpl;  
import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.stereotype.Service;  

/**
 * 调度服务实现类。
 *
 * @author hmilyylimh
 *
 * @version 0.0.1
 *
 * @date 2017/9/18
 *
 */
@Service("schedulerService")  
public class SchedulerServiceImpl implements ISchedulerService {
  
    private static final String NULLSTRING = null;  
    private static final Date NULLDATE = null;  
  
    @Autowired  
    private Scheduler scheduler;  
    @Autowired  
    private JobDetail jobDetail;  
  
    @Override  
    public void schedule(String cronExpression) {  
        schedule(NULLSTRING, cronExpression);  
    }  
  
    @Override  
    public void schedule(String name, String cronExpression) {  
        schedule(name, NULLSTRING, cronExpression);  
    }  
  
    @Override  
    public void schedule(String name, String group, String cronExpression) {  
        try {  
            schedule(name, group, new CronExpression(cronExpression));  
        } catch (ParseException e) {  
            throw new IllegalArgumentException(e);  
        }  
    }  
  
    @Override  
    public void schedule(CronExpression cronExpression) {  
        schedule(NULLSTRING, cronExpression);  
    }  
  
    @Override  
    public void schedule(String name, CronExpression cronExpression) {  
        schedule(name, NULLSTRING, cronExpression);  
    }  
  
    @Override  
    public void schedule(String name, String group, CronExpression cronExpression) {  
  
        if (isValidExpression(cronExpression)) {  
  
            if (name == null || name.trim().equals("")) {  
                name = UUID.randomUUID().toString();  
            }  
  
            CronTriggerImpl trigger = new CronTriggerImpl();  
            trigger.setCronExpression(cronExpression);  
  
            TriggerKey triggerKey = new TriggerKey(name, group);  
  
            trigger.setJobName(jobDetail.getKey().getName());  
            trigger.setKey(triggerKey);  
  
            try {  
                scheduler.addJob(jobDetail, true);  
                if (scheduler.checkExists(triggerKey)) {  
                    scheduler.rescheduleJob(triggerKey, trigger);  
                } else {  
                    scheduler.scheduleJob(trigger);  
                }  
            } catch (SchedulerException e) {  
                throw new IllegalArgumentException(e);  
            }  
        }  
    }  
  
    @Override  
    public void schedule(Date startTime) {  
        schedule(startTime, NULLDATE);  
    }  
  
    @Override  
    public void schedule(Date startTime, String group) {  
        schedule(startTime, NULLDATE, group);  
    }  
  
    @Override  
    public void schedule(String name, Date startTime) {  
        schedule(name, startTime, NULLDATE);  
    }  
  
    @Override  
    public void schedule(String name, Date startTime, String group) {  
        schedule(name, startTime, NULLDATE, group);  
    }  
  
    @Override  
    public void schedule(Date startTime, Date endTime) {  
        schedule(startTime, endTime, 0);  
    }  
  
    @Override  
    public void schedule(Date startTime, Date endTime, String group) {  
        schedule(startTime, endTime, 0, group);  
    }  
  
    @Override  
    public void schedule(String name, Date startTime, Date endTime) {  
        schedule(name, startTime, endTime, 0);  
    }  
  
    @Override  
    public void schedule(String name, Date startTime, Date endTime, String group) {  
        schedule(name, startTime, endTime, 0, group);  
    }  
  
    @Override  
    public void schedule(Date startTime, int repeatCount) {  
        schedule(null, startTime, NULLDATE, 0);  
    }  
  
    @Override  
    public void schedule(Date startTime, Date endTime, int repeatCount) {  
        schedule(null, startTime, endTime, 0);  
    }  
  
    @Override  
    public void schedule(Date startTime, Date endTime, int repeatCount, String group) {  
        schedule(null, startTime, endTime, 0, group);  
    }  
  
    @Override  
    public void schedule(String name, Date startTime, Date endTime, int repeatCount) {  
        schedule(name, startTime, endTime, 0, 0L);  
    }  
  
    @Override  
    public void schedule(String name, Date startTime, Date endTime, int repeatCount, String group) {  
        schedule(name, startTime, endTime, 0, 0L, group);  
    }  
  
    @Override  
    public void schedule(Date startTime, int repeatCount, long repeatInterval) {  
        schedule(null, startTime, NULLDATE, repeatCount, repeatInterval);  
    }  
  
    @Override  
    public void schedule(Date startTime, Date endTime, int repeatCount, long repeatInterval) {  
        schedule(null, startTime, endTime, repeatCount, repeatInterval);  
    }  
  
    @Override  
    public void schedule(Date startTime, Date endTime, int repeatCount, long repeatInterval, String group) {  
        schedule(null, startTime, endTime, repeatCount, repeatInterval, group);  
    }  
  
    @Override  
    public void schedule(String name, Date startTime, Date endTime, int repeatCount, long repeatInterval) {  
        schedule(name, startTime, endTime, repeatCount, repeatInterval, NULLSTRING);  
    }  
  
    @Override  
    public void schedule(String name, Date startTime, Date endTime, int repeatCount, long repeatInterval, String group) {  
  
        if (this.isValidExpression(startTime)) {  
  
            if (name == null || name.trim().equals("")) {  
                name = UUID.randomUUID().toString();  
            }  
  
            TriggerKey triggerKey = new TriggerKey(name, group);  
  
            SimpleTriggerImpl trigger = new SimpleTriggerImpl();  
            trigger.setKey(triggerKey);  
            trigger.setJobName(jobDetail.getKey().getName());  
  
            trigger.setStartTime(startTime);  
            trigger.setEndTime(endTime);  
            trigger.setRepeatCount(repeatCount);  
            trigger.setRepeatInterval(repeatInterval);  
  
            try {  
                scheduler.addJob(jobDetail, true);  
                if (scheduler.checkExists(triggerKey)) {  
                    scheduler.rescheduleJob(triggerKey, trigger);  
                } else {  
                    scheduler.scheduleJob(trigger);  
                }  
            } catch (SchedulerException e) {  
                throw new IllegalArgumentException(e);  
            }  
        }  
    }  
  
    @Override  
    public void pauseTrigger(String triggerName) {  
        pauseTrigger(triggerName, NULLSTRING);  
    }  
  
    @Override  
    public void pauseTrigger(String triggerName, String group) {  
        try {  
            scheduler.pauseTrigger(new TriggerKey(triggerName, group));// 停止触发器  
        } catch (SchedulerException e) {  
            throw new RuntimeException(e);  
        }  
    }  
  
    @Override  
    public void resumeTrigger(String triggerName) {  
        resumeTrigger(triggerName, NULLSTRING);  
    }  
  
    @Override  
    public void resumeTrigger(String triggerName, String group) {  
        try {  
            scheduler.resumeTrigger(new TriggerKey(triggerName, group));// 重启触发器  
        } catch (SchedulerException e) {  
            throw new RuntimeException(e);  
        }  
    }  
  
    @Override  
    public boolean removeTrigdger(String triggerName) {  
        return removeTrigdger(triggerName, NULLSTRING);  
    }  
  
    @Override  
    public boolean removeTrigdger(String triggerName, String group) {  
        TriggerKey triggerKey = new TriggerKey(triggerName, group);  
        try {  
            scheduler.pauseTrigger(triggerKey);// 停止触发器  
            return scheduler.unscheduleJob(triggerKey);// 移除触发器  
        } catch (SchedulerException e) {  
            throw new RuntimeException(e);  
        }  
    }  
  
    private boolean isValidExpression(final CronExpression cronExpression) {  
  
        CronTriggerImpl trigger = new CronTriggerImpl();  
        trigger.setCronExpression(cronExpression);  
  
        Date date = trigger.computeFirstFireTime(null);  
  
        return date != null && date.after(new Date());  
    }  
  
    private boolean isValidExpression(final Date startTime) {  
  
        SimpleTriggerImpl trigger = new SimpleTriggerImpl();  
        trigger.setStartTime(startTime);  
  
        Date date = trigger.computeFirstFireTime(null);  
  
        return date != null && date.after(new Date());  
    }  
}  
2.8 添加调度的任务类(springms-simple-quartz-cluster/src/main/java/com/springms/cloud/task/ScheduleTask.java)
package com.springms.cloud.task;

import org.quartz.JobExecutionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;  
import org.springframework.stereotype.Component;    
    
/**
 * 调度的任务。
 *
 * testScheduleTask 字符串名称在 quartz.xml 中配置为属性 targetObject 的 value 值。
 * sayHello 方法名称在 quartz.xml 中配置为属性 targetMethod 的 value 值。
 *
 * @author hmilyylimh
 *
 * @version 0.0.1
 *
 * @date 2017/9/18
 *
 */
@Configuration    
@Component("testScheduleTask")
@EnableScheduling   
public class ScheduleTask {

    private static final Logger Logger = LoggerFactory.getLogger(ScheduleTask.class);

    public void sayHello(JobExecutionContext context){
        Logger.info("====    sayHello 123456789    ====");
        System.out.println("====    sayHello 123456789    ====");
    }    
}  
2.9 添加Web层Controller测试类(springms-simple-quartz-cluster/src/main/java/com/springms/cloud/controller/QuartzClusterController.java)
package com.springms.cloud.controller;

import com.springms.cloud.service.ISchedulerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

/**
 * QuartzCluster 分布式修改调度服务的Controller。
 *
 * @author hmilyylimh
 *
 * @version 0.0.1
 *
 * @date 2017/9/18
 *
 */
@RestController
public class QuartzClusterController {

    @Autowired
    private ISchedulerService schedulerService;

    /**
     * 每隔多少秒调度一次。
     *
     * @param seconds
     * @return
     */
    @GetMapping("/modify/{seconds}")
    public String modifyStartQuartz(@PathVariable String seconds){
        // eg: 0/10 * * ? * * *
        try {
            schedulerService.schedule("testJobTrigger", "DEFAULT", "0/" + seconds + " * * ? * * *");
        } catch (Exception e) {
            return "Failed";
        }
        return "Successful";
    }
}
2.10 执行 Quartz 的 11 张表入数据库(springms-simple-quartz-cluster/quartz-tables.log)

DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
DROP TABLE IF EXISTS QRTZ_LOCKS;
DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
DROP TABLE IF EXISTS QRTZ_CALENDARS;


CREATE TABLE QRTZ_JOB_DETAILS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    JOB_NAME  VARCHAR(200) NOT NULL,
    JOB_GROUP VARCHAR(200) NOT NULL,
    DESCRIPTION VARCHAR(250) NULL,
    JOB_CLASS_NAME   VARCHAR(250) NOT NULL,
    IS_DURABLE VARCHAR(1) NOT NULL,
    IS_NONCONCURRENT VARCHAR(1) NOT NULL,
    IS_UPDATE_DATA VARCHAR(1) NOT NULL,
    REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
    JOB_DATA BLOB NULL,
    PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
);

CREATE TABLE QRTZ_TRIGGERS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    JOB_NAME  VARCHAR(200) NOT NULL,
    JOB_GROUP VARCHAR(200) NOT NULL,
    DESCRIPTION VARCHAR(250) NULL,
    NEXT_FIRE_TIME BIGINT(13) NULL,
    PREV_FIRE_TIME BIGINT(13) NULL,
    PRIORITY INTEGER NULL,
    TRIGGER_STATE VARCHAR(16) NOT NULL,
    TRIGGER_TYPE VARCHAR(8) NOT NULL,
    START_TIME BIGINT(13) NOT NULL,
    END_TIME BIGINT(13) NULL,
    CALENDAR_NAME VARCHAR(200) NULL,
    MISFIRE_INSTR SMALLINT(2) NULL,
    JOB_DATA BLOB NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
        REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)
);

CREATE TABLE QRTZ_SIMPLE_TRIGGERS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    REPEAT_COUNT BIGINT(7) NOT NULL,
    REPEAT_INTERVAL BIGINT(12) NOT NULL,
    TIMES_TRIGGERED BIGINT(10) NOT NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);

CREATE TABLE QRTZ_CRON_TRIGGERS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    CRON_EXPRESSION VARCHAR(200) NOT NULL,
    TIME_ZONE_ID VARCHAR(80),
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);

CREATE TABLE QRTZ_SIMPROP_TRIGGERS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    STR_PROP_1 VARCHAR(512) NULL,
    STR_PROP_2 VARCHAR(512) NULL,
    STR_PROP_3 VARCHAR(512) NULL,
    INT_PROP_1 INT NULL,
    INT_PROP_2 INT NULL,
    LONG_PROP_1 BIGINT NULL,
    LONG_PROP_2 BIGINT NULL,
    DEC_PROP_1 NUMERIC(13,4) NULL,
    DEC_PROP_2 NUMERIC(13,4) NULL,
    BOOL_PROP_1 VARCHAR(1) NULL,
    BOOL_PROP_2 VARCHAR(1) NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
    REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);

CREATE TABLE QRTZ_BLOB_TRIGGERS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    BLOB_DATA BLOB NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);

CREATE TABLE QRTZ_CALENDARS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    CALENDAR_NAME  VARCHAR(200) NOT NULL,
    CALENDAR BLOB NOT NULL,
    PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
);

CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_GROUP  VARCHAR(200) NOT NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
);

CREATE TABLE QRTZ_FIRED_TRIGGERS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    ENTRY_ID VARCHAR(95) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    INSTANCE_NAME VARCHAR(200) NOT NULL,
    FIRED_TIME BIGINT(13) NOT NULL,
    SCHED_TIME BIGINT(13) NOT NULL,
    PRIORITY INTEGER NOT NULL,
    STATE VARCHAR(16) NOT NULL,
    JOB_NAME VARCHAR(200) NULL,
    JOB_GROUP VARCHAR(200) NULL,
    IS_NONCONCURRENT VARCHAR(1) NULL,
    REQUESTS_RECOVERY VARCHAR(1) NULL,
    PRIMARY KEY (SCHED_NAME,ENTRY_ID)
);

CREATE TABLE QRTZ_SCHEDULER_STATE
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    INSTANCE_NAME VARCHAR(200) NOT NULL,
    LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
    CHECKIN_INTERVAL BIGINT(13) NOT NULL,
    PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
);

CREATE TABLE QRTZ_LOCKS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    LOCK_NAME  VARCHAR(40) NOT NULL,
    PRIMARY KEY (SCHED_NAME,LOCK_NAME)
);


commit;
2.11 添加 Quartz-Cluster 启动类(springms-simple-quartz-cluster/src/main/java/com/springms/cloud/SimpleQuartzClusterApplication.java)
package com.springms.cloud;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;

/**
 * 简单 Quartz-Cluster 微服务,支持集群分布式,并支持动态修改 Quartz 任务的 cronExpression 执行时间。
 *
 * @author hmilyylimh
 *
 * @version 0.0.1
 *
 * @date 17/9/18
 *
 */
@SpringBootApplication
@ImportResource("quartz.xml")
public class SimpleQuartzClusterApplication {

    private static final Logger Logger = LoggerFactory.getLogger(SimpleQuartzClusterApplication.class);

    public static void main(String[] args) {
        Logger.info("简单Quartz-Cluster微服务入口函数编码-" + System.getProperty("file.encoding"));

        SpringApplication.run(SimpleQuartzClusterApplication.class, args);

        System.out.println("【【【【【【 简单Quartz-Cluster微服务 】】】】】】已启动.");
    }
}
三、测试
/****************************************************************************************
 一、简单 Quartz-Cluster 微服务,支持集群分布式,并支持动态修改 Quartz 任务的 cronExpression 执行时间:

 1、添加 Quartz 相关配置文件;
 2、启动 springms-simple-quartz-cluster 模块服务,启动1个端口(8395);
 3、然后查看日志, ScheduleTask 类的 sayHello 方法被有规律的调用,并打印日志出来;

 4、启动 springms-simple-quartz-cluster 模块服务,再启动2个端口(8396、8397);
 5、然后看到 3 台服务器只有 1 台服务器调用了 sayHello 方法,因此 Quartz 的集群分布式也算是部署成功了;
 ****************************************************************************************/

/****************************************************************************************
 二、简单 Quartz-Cluster 微服务,支持集群分布式,并支持动态修改 Quartz 任务的 cronExpression 执行时间(动态修改定时任务的 cronExpression 时间表达式):

 1、添加 Quartz 相关配置文件;
 2、启动 springms-simple-quartz-cluster 模块服务,启动3个端口(8395、8396、8397);
 3、然后看到 3 台服务器只有 1 台服务器调用了 sayHello 方法打印了日志,因此 Quartz 的集群分布式也算是部署成功了;
 4、然后新起网页输入 http://localhost:8395/modify/5 修改定时任务的触发时间;
 5、再等一会儿就看到 3 台服务器只有 1 台服务器每隔 5 秒调用一次 sayHello 方法,因此修改定时任务的克隆表达式也算是成功了;
 ****************************************************************************************/

/****************************************************************************************
 三、简单 Quartz-Cluster 微服务,支持集群分布式,并支持动态修改 Quartz 任务的 cronExpression 执行时间(动态删除其中 1 台活跃 Quartz 服务器,然后剩下的其中 1 台自动接替):

 1、添加 Quartz 相关配置文件;
 2、启动 springms-simple-quartz-cluster 模块服务,启动3个端口(8395、8396、8397);
 3、然后看到 3 台服务器只有 1 台服务器调用了 sayHello 方法打印了日志,因此 Quartz 的集群分布式也算是部署成功了;
 4、然后关闭 1 台活跃 Quartz 服务器;
 5、再等一会儿就看到 2 台服务器中的 1 台服务器每隔一定的时间调用一次 sayHello 方法;
 ****************************************************************************************/
四、下载地址

https://gitee.com/ylimhhmily/SpringCloudTutorial.git

SpringCloudTutorial交流QQ群: 235322432

SpringCloudTutorial交流微信群: 微信沟通群二维码图片链接

欢迎关注,您的肯定是对我最大的支持!!!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/70458.html

相关文章

  • SpringCloud 054 简单 Quartz-Cluster 微服务,采用注解配置 Q

    摘要:加载配置文件失败加载配置文件失败添加定时调度任务定时调度任务添加定时调度任务定时调度任务执行的张表入数据库添加启动类简单微服务,采用注解配置分布式集群。 SpringCloud(第 054 篇)简单 Quartz-Cluster 微服务,采用注解配置 Quartz 分布式集群 - 一、大致介绍 1、因网友提到有没有采用注解式配置的Quartz例子,因此本人就贴上了这样一个样例; 2、至...

    isLishude 评论0 收藏0
  • SpringCloud 046 )注解式Schedule配置定时任务,不支持任务调度

    摘要:当前时间打印当前时间定时任务触发,操作多个添加数据,事务中任一异常,都可以正常导致数据回滚。当前时间当前时间添加微服务启动类注解式配置定时任务,不支持任务调度。 SpringCloud(第 046 篇)注解式Schedule配置定时任务,不支持任务调度 - 一、大致介绍 1、很多时候我们需要隔一定的时间去执行某个任务,为了实现这样的需求通常最普通的方式就是利用多线程来实现; 2、但是有...

    masturbator 评论0 收藏0
  • 2021 年最新基于 Spring Cloud 的微服务架构分析

    摘要:是一个相对比较新的微服务框架,年才推出的版本虽然时间最短但是相比等框架提供的全套的分布式系统解决方案。提供线程池不同的服务走不同的线程池,实现了不同服务调用的隔离,避免了服务器雪崩的问题。通过互相注册的方式来进行消息同步和保证高可用。 Spring Cloud 是一个相对比较新的微服务框架,...

    cikenerd 评论0 收藏0

发表评论

0条评论

xiyang

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<