SpringCloud 整合 Quartz 支持集群,支持動態修改 Quartz 執行時間

SpringCloud 整合 Quartz 支持集群,支持動態修改 Quartz 執行時間


一、添加 maven 引用包




<dependencies>
    <!-- 訪問數據庫模塊 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

    <!-- web模塊 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- MYSQL -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>

    <!-- Jdbc 模塊 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>

    <!-- log4j 日志模塊 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-log4j</artifactId>
    </dependency>

    <!-- quartz 模塊 -->
    <dependency>
        <groupId>org.quartz-scheduler</groupId>
        <artifactId>quartz</artifactId>
        <version>2.3.0</version>
    </dependency>
    <dependency>
        <groupId>org.quartz-scheduler</groupId>
        <artifactId>quartz-jobs</artifactId>
        <version>2.3.0</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
    </dependency>

    <!-- druid 線程池模塊 -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.3</version>
    </dependency>




二、添加 3 個配置文件




   1、src\main\resources\application.yml 文件:

   server:
        port: 8395
   spring:
        application:
            name: microservice-simple-quartz-cluster
        datasource:
            driver-class-name: com.mysql.jdbc.Driver
            url: jdbc:mysql://ip:port/hmilyylimh?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true
            username: username
            password: username
        jpa:
            hibernate:
                ddl-auto: update #ddl-auto:設為update表示每次都不會重新建表
                show-sql: true






    2、src\main\resources\quartz.properties 文件,配置quartz:

    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






    3、src\main\resources\quartz.xml 文件,配置定時任務:

    <?xml version="1.0" encoding="UTF-8"?>  
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
           xmlns:p="http://www.springframework.org/schema/p"
           xmlns:aop="http://www.springframework.org/schema/aop" 
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
                    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
                    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">


<bean id="testJobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
    <!-- durability 表示任務完成之后是否依然保留到數據庫,默認false -->
    <property name="durability" value="true" />
    <property name="requestsRecovery" value="true" />
    <property name="jobClass">
        <value>
            com.itmuch.cloud.job.DetailQuartzJobBean
        </value>
    </property>
    <property name="jobDataAsMap">
        <map>
            <entry key="targetObject" value="testScheduleTask" />
            <entry key="targetMethod" value="sayHello" />
            <!-- 是否允許任務并發執行。當值為false時,表示必須等到前一個線程處理完畢后才再啟一個新的線程 -->
            <entry key="concurrent" value="false" />
        </map>
    </property>
</bean>

<bean id="testJobTrigger"
      class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
    <property name="jobDetail">
        <ref bean="testJobDetail" />
    </property>
    <property name="cronExpression">
        <value>0/10 * * * * ?</value><!--每10秒鐘執行一次 -->
    </property>
</bean>

<bean id="startQuertz" lazy-init="false" autowire="no"
      class="org.springframework.scheduling.quartz.SchedulerFactoryBean"
      destroy-method="destroy">
    <!--QuartzScheduler 啟動時更新己存在的Job,這樣就不用每次修改targetObject后刪除qrtz_job_details表對應記錄了 -->
    <property name="overwriteExistingJobs" value="true" />
    <property name="startupDelay" value="2" />
    <property name="autoStartup" value="true" />
    <property name="triggers">
        <list>
            <ref bean="testJobTrigger" />
        </list>
    </property>
    <property name="dataSource" ref="dataSource" />
    <property name="applicationContextSchedulerContextKey" value="applicationContext" />
    <property name="configLocation" value="classpath:quartz.properties" />
</bean>

    </beans> 




三、DetailQuartzJobBean 加載類和方法




package com.itmuch.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;


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


}




四、調度服務接口




package com.itmuch.cloud.service;


import java.util.Date;


import org.quartz.CronExpression;


/**
* 調度服務接口。
*
* @date 2017/9/16
*
*/
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);  


}




五、調度服務接口實現類




package com.itmuch.cloud.service.impl;


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


import com.itmuch.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;


/**
* 調度服務實現類。
*
* @date 2017/9/16
*
*/
@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());  
}  


}




六、調度的任務類




package com.itmuch.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 值。
*
* @date 2017/9/16
*
*/
@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    ====");
}    


}




七、執行 Quartz 的 11 張表入數據庫




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;




八、簡單Quartz-Cluster微服務啟動類




package com.itmuch.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微服務。
*
* @date 2017/9/16
*
*/
@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微服務:


1、添加 Quartz 相關配置文件;
2、啟動 microservice-simple-quartz-cluster 模塊服務,啟動1個端口(8395);
3、然后查看日志, ScheduleTask 類的 sayHello 方法被有規律的調用,并打印日志出來;


4、啟動 microservice-simple-quartz-cluster 模塊服務,再啟動2個端口(8396、8397);
5、然后看到 3 臺服務器只有 1 臺服務器調用了 sayHello 方法,因此 Quartz 的集群分布式也算是部署成功了;
******************************************************************************/


/******************************************************************************
二、簡單Quartz-Cluster微服務(動態修改定時任務的 cronExpression 時間表達式):


1、添加 Quartz 相關配置文件;
2、啟動 microservice-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微服務(動態刪除其中 1 臺活躍 Quartz 服務器,然后剩下的其中 1 臺自動接替):


1、添加 Quartz 相關配置文件;
2、啟動 microservice-simple-quartz-cluster 模塊服務,啟動3個端口(8395、8396、8397);
3、然后看到 3 臺服務器只有 1 臺服務器調用了 sayHello 方法打印了日志,因此 Quartz 的集群分布式也算是部署成功了;
4、然后關閉 1 臺活躍 Quartz 服務器;
5、再等一會兒就看到 2 臺服務器中的 1 臺服務器每隔一定的時間調用一次 sayHello 方法;
******************************************************************************/



最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,345評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,494評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,283評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,953評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,714評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,410評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,940評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,776評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,976評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,210評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,642評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,878評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,654評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,958評論 2 373

推薦閱讀更多精彩內容

  • Quartz 中集群如何工作 一個 Quartz 集群中的每個節點是一個獨立的 Quartz 應用,它又管理著其他...
    那臉憔悴閱讀 2,763評論 1 52
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,781評論 18 139
  • 一. Java基礎部分.................................................
    wy_sure閱讀 3,826評論 0 11
  • scheduler定時調度系統是大多行業項目都需要的,傳統的spring-job模式,個人感覺已經out了,因為存...
    安琪拉_4b7e閱讀 2,848評論 4 6
  • 90歲高齡的卡斯特羅離我們而去了,電視里熟悉的綠軍裝和絡腮胡子就這么走了。 “老卡”在很多方面,都不能不說是我們這...
    六月荷聽雨閱讀 354評論 0 1