SpringCloud(第 054 篇)简单 Quartz-Cluster 微服务,采用注解配置 Quartz 分布式集群

来源:互联网 发布:为什么金九银十 知乎 编辑:程序博客网 时间:2024/05/21 10:53

SpringCloud(第 054 篇)简单 Quartz-Cluster 微服务,采用注解配置 Quartz 分布式集群

-

一、大致介绍

1、因网友提到有没有采用注解式配置的Quartz例子,因此本人就贴上了这样一个样例;2、至于如何修改定时任务的 cronExpression 表达式值的话,大家可以参照之前的(第 010 篇)样子看看如何修改;3、注意:配置文件中的 mysql 数据库链接配置大家就各自配置自己的哈;

二、实现步骤

2.1 添加 maven 引用包

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <artifactId>springms-simple-quartz-config-cluster</artifactId>    <version>1.0-SNAPSHOT</version>    <packaging>jar</packaging>    <parent>        <groupId>com.springms.cloud</groupId>        <artifactId>springms-spring-cloud</artifactId>        <version>1.0-SNAPSHOT</version>    </parent>    <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>        <!-- 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>    </dependencies></project>

2.2 添加应用配置文件(springms-simple-quartz-config-cluster\src\main\resources\application.yml)

server:  port: 8405spring:  application:    name: springms-simple-quartz-config-cluster  #全部小写###################################################################################################### mysql 属性配置  datasource:    driver-class-name: com.mysql.jdbc.Driver    url: jdbc:mysql://ip:3306/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########################################################################################################################################################################################################### 打印日志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-config-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.StdJDBCDelegateorg.quartz.jobStore.tablePrefix = QRTZ_  org.quartz.jobStore.isClustered = true  org.quartz.jobStore.useProperties = falseorg.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 添加数据源配置类(springms-simple-quartz-config-cluster\src\main\java\com\springms\cloud\config\DataSourceConfig.java)

package com.springms.cloud.config;import org.apache.tomcat.jdbc.pool.DataSource;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.core.env.Environment;import javax.annotation.Resource;/** * 数据源配置。 * * @author hmilyylimh * * @version 0.0.1 * * @date 2017/12/17 * */@Configurationpublic class DataSourceConfig {    @Resource    private Environment env;    @Bean    public DataSource dataSource(){        DataSource configDataSource = new DataSource();        configDataSource.setUrl("jdbc:mysql://ip:3306/hmilyylimh?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true");        configDataSource.setDriverClassName("com.mysql.jdbc.Driver");        configDataSource.setUsername("username");        configDataSource.setPassword("password");        configDataSource.setInitialSize(5);        configDataSource.setDefaultAutoCommit(true);        if(configDataSource.getUrl().startsWith("jdbc:mysql://ip")){            throw new RuntimeException("请配置数据源地址");        }        if(configDataSource.getUsername().startsWith("username")){            throw new RuntimeException("请配置数据源用户名");        }        if(configDataSource.getPassword().startsWith("password")){            throw new RuntimeException("请配置数据源密码");        }        // 这些配置看个人需要,需要的话可以全部配置起来,我这里写Demo的话就没有全部配置起来了        //configDataSource.setInitialSize();        //configDataSource.setMinEvictableIdleTimeMillis();        //configDataSource.setNumTestsPerEvictionRun();        //configDataSource.setTestWhileIdle();        //configDataSource.setMaxActive();        //configDataSource.setMaxIdle();        //configDataSource.setMinIdle();        //configDataSource.setMaxWait();        //configDataSource.setRemoveAbandoned();        //configDataSource.setRemoveAbandonedTimeout();        //configDataSource.setValidationQuery();        //configDataSource.setValidationQueryTimeout();        //configDataSource.setValidationInterval();        //configDataSource.setTimeBetweenEvictionRunsMillis();        return configDataSource;    }}

2.5 添加Quartz调度配置类(springms-simple-quartz-config-cluster\src\main\java\com\springms\cloud\config\QuartzSchedulerConfig.java)

package com.springms.cloud.config;import com.springms.cloud.job.Job1;import com.springms.cloud.job.Job2;import org.apache.tomcat.jdbc.pool.DataSource;import org.quartz.CronTrigger;import org.quartz.JobDetail;import org.quartz.spi.JobFactory;import org.quartz.spi.TriggerFiredBundle;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.beans.factory.config.AutowireCapableBeanFactory;import org.springframework.beans.factory.config.PropertiesFactoryBean;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.core.io.ClassPathResource;import org.springframework.scheduling.quartz.CronTriggerFactoryBean;import org.springframework.scheduling.quartz.JobDetailFactoryBean;import org.springframework.scheduling.quartz.SchedulerFactoryBean;import org.springframework.scheduling.quartz.SpringBeanJobFactory;import java.io.IOException;import java.util.Properties;/** * Quartz调度配置类。 * * @author hmilyylimh * * @version 0.0.1 * * @date 2017/12/17 * */@Configurationpublic class QuartzSchedulerConfig {    @Autowired    private DataSource dataSource;    private static final Logger Logger = LoggerFactory.getLogger(QuartzSchedulerConfig.class);    private static final String QUARTZ_PROPERTIES_NAME = "/quartz.properties";    @Bean    public JobFactory jobFactory(ApplicationContext applicationContext) {        AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();        jobFactory.setApplicationContext(applicationContext);        return jobFactory;    }    @Bean    public SchedulerFactoryBean schedulerFactoryBean(JobFactory jobFactory, CronTrigger[] cronTrigger, JobDetail[]            jobDetails) {        SchedulerFactoryBean factoryBean = new SchedulerFactoryBean();        try {            factoryBean.setQuartzProperties(quartzProperties());            factoryBean.setDataSource(dataSource);            factoryBean.setJobFactory(jobFactory);            factoryBean.setTriggers(cronTrigger);            factoryBean.setJobDetails(jobDetails);            factoryBean.setOverwriteExistingJobs(true);        } catch (Exception e) {            Logger.error("加载 {} 配置文件失败.", QUARTZ_PROPERTIES_NAME, e);            throw new RuntimeException("加载配置文件失败", e);        }        return factoryBean;    }    @Bean(name = "job1Trigger")    public CronTriggerFactoryBean job1Trigger(@Qualifier("job1Detail") JobDetail jobDetail) {        CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean();        cronTriggerFactoryBean.setJobDetail(jobDetail);        cronTriggerFactoryBean.setCronExpression("0/15 * * * * ?");        return cronTriggerFactoryBean;    }    @Bean(name = "job1Detail")    public JobDetailFactoryBean job1Detail() {        JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean();        jobDetailFactoryBean.setJobClass(Job1.class);        jobDetailFactoryBean.setDurability(true);        return jobDetailFactoryBean;    }    @Bean(name = "job2Trigger")    public CronTriggerFactoryBean job2Trigger(@Qualifier("job2Detail") JobDetail jobDetail) {        CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean();        cronTriggerFactoryBean.setJobDetail(jobDetail);        cronTriggerFactoryBean.setCronExpression("0/5 * * * * ?");        return cronTriggerFactoryBean;    }    @Bean(name = "job2Detail")    public JobDetailFactoryBean job2Detail() {        JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean();        jobDetailFactoryBean.setJobClass(Job2.class);        jobDetailFactoryBean.setDurability(true);        return jobDetailFactoryBean;    }    @Bean    public Properties quartzProperties() throws IOException {        PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();        propertiesFactoryBean.setLocation(new ClassPathResource(QUARTZ_PROPERTIES_NAME));        propertiesFactoryBean.afterPropertiesSet();        return propertiesFactoryBean.getObject();    }    class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {        private transient AutowireCapableBeanFactory beanFactory;        @Override        public void setApplicationContext(final ApplicationContext context) {            beanFactory = context.getAutowireCapableBeanFactory();        }        @Override        protected Object createJobInstance(final TriggerFiredBundle bundle)                throws Exception {            final Object job = super.createJobInstance(bundle);            beanFactory.autowireBean(job);            return job;        }    }}

2.6 添加定时调度任务Job1(springms-simple-quartz-config-cluster\src\main\java\com\springms\cloud\job\Job1.java)

package com.springms.cloud.job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;import org.springframework.scheduling.quartz.QuartzJobBean;import org.springframework.stereotype.Component;import java.text.SimpleDateFormat;import java.util.Date;/** * 定时调度任务Job1. * * @author hmilyylimh * * @version 0.0.1 * * @date 2017/12/17 * */@Componentpublic class Job1 extends QuartzJobBean {    @Override    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {        System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");        System.out.println("@@@@@@@@@@@@        "+(new SimpleDateFormat("yyyy-mm-dd HH:mm:ss.SSSSSS")).format(new Date())+"         @@@@@@@@@@@");        System.out.println("@@@@@@@@@@@@@@@@@@@@@@@        Job1         @@@@@@@@@@@@@@@@@@@@@@");        System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");        System.out.println();    }}

2.7 添加定时调度任务Job2(springms-simple-quartz-config-cluster\src\main\java\com\springms\cloud\job\Job2.java)

package com.springms.cloud.job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.scheduling.quartz.QuartzJobBean;import java.text.SimpleDateFormat;import java.util.Date;/** * 定时调度任务Job2. * * @author hmilyylimh * * @version 0.0.1 * * @date 2017/12/17 * */public class Job2 extends QuartzJobBean {    @Override    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {        System.out.println("==================================================================");        System.out.println("===========        "+(new SimpleDateFormat("yyyy-mm-dd HH:mm:ss.SSSSSS")).format(new Date())+"         ============");        System.out.println("=======================        Job2         ======================");        System.out.println("==================================================================");        System.out.println();    }}

2.8 执行 Quartz 的 11 张表入数据库(springms-simple-quartz-config-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.9 添加 Quartz-Cluster 启动类(springms-simple-quartz-config-cluster\src\main\java\com\springms\cloud\SimpleQuartzConfigClusterApplication.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 分布式集群。 * * @author hmilyylimh * * @version 0.0.1 * * @date 2017/12/17 * */@SpringBootApplicationpublic class SimpleQuartzConfigClusterApplication {    private static final Logger Logger = LoggerFactory.getLogger(SimpleQuartzConfigClusterApplication.class);    public static void main(String[] args) {        SpringApplication.run(SimpleQuartzConfigClusterApplication.class, args);        System.out.println("【【【【【【 简单Quartz-Config-Cluster微服务 】】】】】】已启动.");    }}

三、测试

/**************************************************************************************** 一、简单 Quartz-Cluster 微服务,采用注解配置 Quartz 分布式集群: 1、添加 Quartz 相关配置文件; 2、启动 springms-simple-quartz-config-cluster 模块服务,启动3个端口(8405、8406、8407); 3、然后看到 3 台服务器只有 1 台服务器调用了 Job1 类中的方法,因此 Quartz 的集群分布式也算是部署成功了; 4、然后关闭 1 台活跃 Quartz 服务器; 5、再等一会儿就看到 2 台服务器中的 1 台服务器每隔一定的时间调用 Job1 类中的方法; ****************************************************************************************/

四、下载地址

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

SpringCloudTutorial交流QQ群: 235322432

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

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

阅读全文
0 0
原创粉丝点击