SpringBoot集成Quartz数据库配置定时任务

文章参考

https://blog.csdn.net/l18848956739/article/details/86597709

https://blog.csdn.net/xibei19921101/article/details/105012749

https://blog.csdn.net/WLPJLP/article/details/103908448

https://blog.csdn.net/sqlgao22/article/details/100669377

quartz


        如果仅仅只是使用定时任务,可以使用spring的schedule实现,方便,代码量少.易于实现,但是,
当使用分布式进行项目部署的时候,就会出现所有的服务器都在跑同一个定时,出现一个定时任务执行多次的情况,会出现很多问题,使用quartz进行定时任务的调度就可以避免这个问题。

quartz的优点

        1.可以实现多个定时任务进行调度。

        2.可以实现与代码的解耦,通过配置文件的方式进行配置。

        3.功能强大,可以通过cron表达式设置复杂的时间任务调度。

quartz核心:

1.job:(被任务调度的接口),我们需要实现job接口,和继承TimerTask重写run方法一样,重写job中的excute方法,excute方法是任务调度的方法执行位置。

2.JobDetail:必须通过JobDetail来实现Job实例,(基于builder模式实现的)

3.trigger(包括:CronTrigger 和simpleTrigger):指定任务调度的频率时间。何时进行任务调度(基于builder模式实现的)触发器

4.scheduler:结合jobdetail 实例和trigger实例,进行调度的触发的调度器(基于factory模式)。

Quartz 中集群如何工作


一个 Quartz 集群中的每个节点是一个独立的 Quartz 应用,它又管理着其他的节点。意思是你必须对每个节点分别启动或停止。不像许多应用服务器的集群,独立的 Quartz 节点并不与另一其的节点或是管理节点通信。Quartz 应用是通过数据库表来感知到另一应用的。离开了db将无法感知.
 

在这里插入图片描述

项目功能 

1、springboot集成quartz,使用druid连接池 
2、支持http请求任务定时调度,当前支持get、post 请求类型,并记录返回内容
3、通过web界面进行任务管理,包括任务暂停、恢复、修改、历史记录、历史任务查看功能
4、支持调用接口(/quartz/httpJob/add)进行任务添加  
5、根据jobName或jobGroup进行查询

1.导入数据库表

因为Quartz 集群依赖于数据库,所以必须首先创建Quartz数据库表。Quartz 包括了所有被支持的数据库平台的 SQL 脚本。这是是mysql,其他数据库官网下载

注意:创建的表表名都是小写的,在代码中使用的是大写的表名;在liunx中的mysql数据库默认是大小写敏感的,因此使用liunx的数据库会出现找不到表的情况,酌情修改表或是改变数据库配置
表中所有字段详解: quartz中表及其表字段的意义_sqlgao22的博客-CSDN博客

CREATE DATABASE `quartz` CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';
USE quartz;
-- QUARTZ_TABLE
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;

--  quartz自带表结构

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))
ENGINE=InnoDB;

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))
ENGINE=InnoDB;

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))
ENGINE=InnoDB;

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(120) 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))
ENGINE=InnoDB;

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))
ENGINE=InnoDB;

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),
INDEX (SCHED_NAME,TRIGGER_NAME, TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;

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))
ENGINE=InnoDB;

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

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))
ENGINE=InnoDB;

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))
ENGINE=InnoDB;

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

CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY ON QRTZ_JOB_DETAILS(SCHED_NAME,REQUESTS_RECOVERY);
CREATE INDEX IDX_QRTZ_J_GRP ON QRTZ_JOB_DETAILS(SCHED_NAME,JOB_GROUP);

CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME);
CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);

CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME);
CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);



-- 定时任务
DROP TABLE IF EXISTS schedule_job;

CREATE TABLE schedule_job(

 ID BIGINT (50) NOT NULL AUTO_INCREMENT COMMENT '任务id',
 JOB_NAME VARCHAR (100) NOT NULL COMMENT '任务名称',
 JOB_GROUP VARCHAR (100) NOT NULL COMMENT '任务分组',
 DESCRIPTION VARCHAR (100) NOT NULL COMMENT '任务描述',
 cron_expression VARCHAR (200) NOT NULL COMMENT 'cron表达式',
 TASK_STATUS VARCHAR (20) NOT NULL COMMENT '任务状态',
 REQUEST_TYPE VARCHAR (50) NOT NULL COMMENT '请求类型{GET或POST请求}',
 HTTP_URL VARCHAR (256) NOT NULL COMMENT '请求url',
 HTTP_PARAMS VARCHAR (20000) COMMENT '请求参数',
 CREATE_TIME datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
 UPDATE_TIME datetime COMMENT '修改时间',
 PRIMARY KEY (ID)

) ENGINE = INNODB DEFAULT CHARSET = utf8 COMMENT = '定时任务';



--  定时任务日志
DROP TABLE IF EXISTS schedule_job_log;

CREATE TABLE schedule_job_log(

ID BIGINT (50) NOT NULL AUTO_INCREMENT COMMENT '日志id',
JOB_ID BIGINT (100) NOT NULL COMMENT '任务id',
JOB_NAME VARCHAR (100) NOT NULL COMMENT '任务名称',
JOB_GROUP VARCHAR (100) NOT NULL COMMENT '任务分组',
DESCRIPTION VARCHAR (100) COMMENT '任务描述',
cron_expression VARCHAR (100) NOT NULL COMMENT 'cron表达式',
TASK_STATUS VARCHAR (20) NOT NULL COMMENT '任务状态 0:成功,1:失败',
REQUEST_TYPE VARCHAR (50) NOT NULL COMMENT '请求类型',
HTTP_URL VARCHAR (256) NOT NULL COMMENT '请求url',
HTTP_PARAMS VARCHAR (20000) COMMENT '请求参数',
times INT (11) COMMENT '耗时(单位:毫秒)',
CREATE_TIME datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
UPDATE_TIME datetime COMMENT '修改时间',
PRIMARY KEY (ID)

) ENGINE = INNODB DEFAULT CHARSET = utf8 COMMENT = '定时任务日志表';

ALTER TABLE schedule_job ADD UNIQUE INDEX `UNIQUEIDX_SCHEDULE_JOB`(`JOB_NAME`, `JOB_GROUP`);
ALTER TABLE schedule_job_log ADD INDEX `IDX_SCHEDULE_JOB_LOG`(`JOB_NAME`, `JOB_GROUP`);

INSERT INTO `httpjob_details` VALUES ('1', 'task_ce', 'web', '测试无参数job', '* * * * * ?' , null,'POST_JSON', 'http://localhost:8080/quartz/test/job', '', '2021-09-22 10:33:00', null);
INSERT INTO `httpjob_details` VALUES ('9', 'task3', 'adce', '测试有参数job' , '* * * * * ?', '0' ,'POST_JSON', 'http://localhost:8080/quartz/test/job', '	\r\n{\r\n  \"jobName\": \"task3\",\r\n  \"jobGroup\": \"adce\"\r\n}', '2021-09-24 16:28:11', null);


commit;

2.引入pom依赖



        
            org.springframework.boot
            spring-boot-starter
        

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

        
            org.springframework
            spring-context-support
        

        
            org.springframework.boot
            spring-boot-starter-test
            test
        

        
            mysql
            mysql-connector-java
            5.1.46
            runtime
        

        
            org.mybatis.spring.boot
            mybatis-spring-boot-starter
            1.3.2
        

        
        
            org.quartz-scheduler
            quartz
            2.2.3
        
        
            org.quartz-scheduler
            quartz-jobs
            2.2.3
        

        
        
            org.apache.httpcomponents
            httpclient
            4.5.6
        

        
        
            org.apache.commons
            commons-lang3
            3.8.1
        

        
        
            com.alibaba
            fastjson
            1.2.53
        

        
        
            com.alibaba
            druid
            1.1.9
        
        
            com.github.pagehelper
            pagehelper-spring-boot-starter
            1.2.5
        
        
            org.projectlombok
            lombok
            1.18.4
        

        
            io.springfox
            springfox-swagger2
            2.7.0
        
        
            io.springfox
            springfox-swagger-ui
            2.7.0
        
    

3.application.properties配置

server.port=8080

#UTF-8字符过滤
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true

# mysql
spring.datasource.url=jdbc:mysql://localhost:3306/quartz?useUnicode=true&characterEncoding=utf-8&useSSL=false&zeroDateTimeBehavior=convertToNull
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driverClassName=com.mysql.jdbc.Driver

# druid连接池的配置信息
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.initialSize=5
spring.datasource.minIdle=5
spring.datasource.maxActive=20
spring.datasource.maxWait=60000
spring.datasource.timeBetweenEvictionRunsMillis=60000
spring.datasource.minEvictableIdleTimeMillis=300000
spring.datasource.validationQuery=SELECT 1 FROM DUAL
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.testOnReturn=false
spring.datasource.poolPreparedStatements=true
spring.datasource.maxPoolPreparedStatementPerConnectionSize=20
spring.datasource.filters=stat
spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000

# mybatis Mapper文件
mybatis.mapper-locations=classpath*:mappings/*.xml
# mybatis别名配置
mybatis.type-aliases-package=com.example.quartz.model

引入quartz.properties配置

注意:使用分布式集群跑定时任务时,需要使用到db持久化,所以需要所有的节点共享一个数据源.
关键配置都有注释

#quartz集群配置
# ===========================================================================
# Configure Main Scheduler Properties 调度器属性
# ===========================================================================
#调度标识名 集群中每一个实例都必须使用相同的名称
org.quartz.scheduler.instanceName: MyQuartzScheduler
#ID设置为自动获取 每一个必须不同
org.quartz.scheduler.instanceId: AUTO
#============================================================================
# Configure ThreadPool
#============================================================================
#线程池的实现类(一般使用SimpleThreadPool即可满足几乎所有用户的需求)
org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
#指定线程数,至少为1(无默认值)(一般设置为1-100直接的整数合适)
org.quartz.threadPool.threadCount: 25
#设置线程的优先级(最大为java.lang.Thread.MAX_PRIORITY 10,最小为Thread.MIN_PRIORITY 1,默认为5)
org.quartz.threadPool.threadPriority: 5
#============================================================================
# Configure JobStore
#============================================================================
# 信息保存时间 默认值60秒,misfire任务为错过调度触发时间的任务,超过60000ms后被判定为misfire
org.quartz.jobStore.misfireThreshold: 60000
#数据保存方式为数据库持久化
org.quartz.jobStore.class: org.quartz.impl.jdbcjobstore.JobStoreTX
#数据库代理类,一般org.quartz.impl.jdbcjobstore.StdJDBCDelegate可以满足大部分数据库
org.quartz.jobStore.driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#JobDataMaps是否都为String类型
org.quartz.jobStore.useProperties: false
#数据库别名 随便取
org.quartz.jobStore.dataSource: myDS
#表的前缀,默认QRTZ_
org.quartz.jobStore.tablePrefix: QRTZ_
#是否加入集群
org.quartz.jobStore.isClustered: true
#调度实例失效的检查时间间隔
org.quartz.jobStore.clusterCheckinInterval: 20000
#避免集群环境下job重复执行
org.quartz.jobStore.acquireTriggersWithinLock: true

4.springboot的配置类

(1)druid数据源配置类


import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.wall.WallFilter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * druid数据源配置类
 */
@Configuration
public class DataSourceConfig {

    @Value("${spring.datasource.url}")
    private String dbUrl;

    @Value("${spring.datasource.username}")
    private String userName;

    @Value("${spring.datasource.password}")
 

你可能感兴趣的:(SpringBoot,big,data,spring,boot)