认识自己的无知是认识世界最可靠的方法————互联网中的无名之辈
关于定时任务
为什么要定时任务?
就拿银行举个例子,大家发现没有,银行的工作时间非常规律,一般下午5~6点就都下班了,那么银行晚上在干什么呢?
银行在夜间需要对白天发送的所有交易进行对账、结账、日切、出报表…
这些工作的工作量都是非常大的,如果统计分析系统直接连上核心系统,那么出报表、自助分析等等这些事情就会给核心系统造成额外的压力。事实上,银行不能容忍统计分析工作影响存取款这种核心业务的。但是,统计分析又不能不做。可行的办法就是每天晚上,在核心业务系统比较空闲的时候,把明细数据转移到统计分析专用的数据仓库去。在数据仓库中再做各种计算,保存结果,给各种统计分析系统使用。这样的数据转移和统计分析计算,一般是定时执行、分批执行的,因此叫做数据跑批。
所以定时任务一般是为系统去完成一些异步、大批次的任务,比如bilibili 每周给UP主推送的周报、CSDN每周推送的小结…
Quartz,为什么是你?
quartz 官网 对它的介绍:
- Quartz是功能强大的开源作业调度库,几乎可以集成到任何Java应用程序中-从最小的独立应用程序到最大的电子商务系统。
- Quartz可用于创建简单或复杂的计划,以执行数以万计,数以万计的工作。
- 任务定义为标准Java组件的作业,它们实际上可以执行您可以编写的所有内容。
- Quartz Scheduler包含许多企业级功能,例如对JTA事务和集群的支持。
我认为Quartz的成功之在于本身对集群的友好支持,通过数据库去维护任务进度,标准任务不会漏跑和重跑,服务器宕机之后能够接着包之前未完成的任务。
下图右图是SpringTask的示意图,Spring Task 的任务是通过Bean的方式实现的,所以只能运行于单机环境,要是部署了集群意味着所以节点都会去执行一次相同的任务。左边是Quartz的集群架构示意图,其任务的信息维护在数据库中,所以能够部署多个节点去执行不同的任务。
Quartz的三要素
- Job : 具体要执行的业务逻辑,比如:发送邮件、同步数据… …
- Trigger:用来定义Job(任务)触发条件、触发时间,触发间隔,终止时间等。
- Scheduler : 调度器是Quartz框架的心脏,用来管理触发器和Job,并保证Job能被触发执行。
SpringBoot2集成Quartz
0. 环境说明
数据库 : MySQL Version : 8
SpringBoot : 2.1.0.RELEASE
JDK : 1.8
Maven : 3.6
流程 : 前端发送请求 ---> 后台Controller拦截 ---> 调度器执行任务
1. 创建数据库和数据表
create database quartz;
use quartz;
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