惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

GbyAI
GbyAI
T
Tenable Blog
Webroot Blog
Webroot Blog
L
Lohrmann on Cybersecurity
S
Securelist
S
Schneier on Security
NISL@THU
NISL@THU
Know Your Adversary
Know Your Adversary
C
Cybersecurity and Infrastructure Security Agency CISA
T
The Exploit Database - CXSecurity.com
L
LINUX DO - 热门话题
C
CXSECURITY Database RSS Feed - CXSecurity.com
O
OpenAI News
I
Intezer
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
TaoSecurity Blog
TaoSecurity Blog
S
Secure Thoughts
Application and Cybersecurity Blog
Application and Cybersecurity Blog
P
Privacy International News Feed
H
Hacker News: Front Page
N
Netflix TechBlog - Medium
M
MIT News - Artificial intelligence
博客园 - Franky
PCI Perspectives
PCI Perspectives
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Microsoft Azure Blog
Microsoft Azure Blog
MongoDB | Blog
MongoDB | Blog
L
LangChain Blog
P
Proofpoint News Feed
S
Security Affairs
WordPress大学
WordPress大学
The Last Watchdog
The Last Watchdog
S
SegmentFault 最新的问题
小众软件
小众软件
F
Full Disclosure
博客园 - 叶小钗
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
T
The Blog of Author Tim Ferriss
Simon Willison's Weblog
Simon Willison's Weblog
P
Palo Alto Networks Blog
Security Latest
Security Latest
P
Proofpoint News Feed
月光博客
月光博客
T
Tailwind CSS Blog
Scott Helme
Scott Helme
Hacker News - Newest:
Hacker News - Newest: "LLM"
Google Online Security Blog
Google Online Security Blog
T
Threat Research - Cisco Blogs
Help Net Security
Help Net Security
Project Zero
Project Zero

Java技术经验分享

生产故障处理SOP分享 | Java技术经验分享 系统稳定性建设实践总结【转载】 | Java技术经验分享 valine访问leancloud国际版异常,评论失效修复 | Java技术经验分享 匆匆忙忙的2021 | Java技术经验分享 聊一下换工作 | Java技术经验分享 IoT系列(2):WIFI设备常见配网方案介绍 | Java技术经验分享 IoT系列(1):什么是物联网 | Java技术经验分享 Java8特性2 - StreamApi | Java技术经验分享 Java8特性1 - lambda表达式&函数式接口 | Java技术经验分享 设计模式(5)-适配器模式 | Java技术经验分享 设计模式(4)-建造者模式 | Java技术经验分享 设计模式(3)-原型模式与浅拷贝和深拷贝 | Java技术经验分享 设计模式(2)-工厂模式图文介绍 | Java技术经验分享 设计模式(1)-带你了解3类8种单例模式 | Java技术经验分享 Java时间处理5---Java8中时区相关类库介绍 | Java技术经验分享 Java时间处理4---Java8中LocalDate、LocalTime、LocalDateTime介绍 | Java技术经验分享 Java时间处理3---Java8中Instant、Duration、Period、Clock介绍 | Java技术经验分享 一些有意思的问答 | Java技术经验分享 Nacos系列博客说明 | Java技术经验分享 菜鸡程序员的2019年度总结 | Java技术经验分享 Java中“附近的人”实现方案讨论及代码实现 | Java技术经验分享 Java时间处理2----时区TimeZone类方法探究(Java8以前) | Java技术经验分享 Java时间处理1----Date和Calendar方法探究(Java8以前) | Java技术经验分享 FastJson中JSONString、JavaBean、JSONObject、JSONArray的转换关系及API示例 | Java技术经验分享 2019.11软考软件设计师归来心得体会及复习备考指南 | Java技术经验分享 你还没用过“约定式提交”吗?那你赶紧来补补知识吧 | Java技术经验分享 教你如何看懂UML中的类图及类图中的关系 | Java技术经验分享 设计模式总览 | Java技术经验分享 萌新入门Github请看这里,学不会远程教 | Java技术经验分享 Hexo的工作原理探究 | Java技术经验分享 Hexo-theme-butterfly修改调整记录教程 | Java技术经验分享 排序8:基数排序 | Java技术经验分享 排序7:归并排序 | Java技术经验分享 排序6:快速排序 | Java技术经验分享 排序5:冒泡排序 | Java技术经验分享 排序4:堆排序 | Java技术经验分享 排序3:选择排序 | Java技术经验分享 排序2:希尔排序 | Java技术经验分享 排序1:直接插入排序 | Java技术经验分享 推荐一款博客一文多发的良心工具OpenWrite | Java技术经验分享 近期学习计划 | Java技术经验分享 Nacos(九):Nacos集群部署和遇到的问题 | Java技术经验分享 Nacos(八):Nacos持久化 | Java技术经验分享 Nacos(七):Nacos共享配置 | Java技术经验分享 Nacos(六):多环境下如何“管理”及“隔离”配置和服务 | Java技术经验分享 Nacos(五):多环境下如何“读取”Nacos中相应的配置 | Java技术经验分享 Nacos(四):SpringCloud项目中接入Nacos作为配置中心 | Java技术经验分享 Nacos(三):Nacos与OpenFeign的对接使用 | Java技术经验分享 Nacos(二):SpringCloud项目中接入Nacos作为注册中心 | Java技术经验分享 Nacos(一):Nacos介绍 | Java技术经验分享 20190719小组分享 | Java技术经验分享 Java中equals和HashCode方法的分析 | Java技术经验分享 Java中==和equals方法的分析 | Java技术经验分享 Java中的自动拆装箱、装箱缓存 | Java技术经验分享 About-blog | Java技术经验分享 Java中的编译、反编译和反编译工具全家桶分享 | Java技术经验分享 finalize()的生命周期(执行过程) | Java技术经验分享 Java关键字之final、finally与finalize方法 | Java技术经验分享 Java中重写、重载 | Java技术经验分享 Java中面向对象的三大特征:继承、封装、多态 | Java技术经验分享 DockerFile介绍 | Java技术经验分享 Docker环境下安装Gitlab | Java技术经验分享 Docker中私有仓库的搭建流程 | Java技术经验分享 Centos7下两种方式安装Docker-CE | Java技术经验分享 Vert.x创建一个Http服务 | Java技术经验分享 Vert.x创建TCP服务端及客户端 | Java技术经验分享 Vert.x Core(二)- Event Bus(事件总线) | Java技术经验分享 Vert.x-Core(一)- 基础篇 | Java技术经验分享 SpringBoot项目中实现国际化 | Java技术经验分享 Vert.x介绍 | Java技术经验分享 毕设选题项目本地运行环境搭建教程 | Java技术经验分享 Jupyter Notebooks的安装和使用介绍 | Java技术经验分享 算法笔试题:1元,5元,10元,20元,50元、100元面值人民币组合给定x元的问题 | Java技术经验分享 SpringBoot2.x集成Redis | Java技术经验分享 SpringBoot2.x集成MongoDB | Java技术经验分享 [SpringCloud学习] - 浅谈微服务架构 | Java技术经验分享 基于hexo和coding免费搭建个人博客网站 | Java技术经验分享 Hello World | Java技术经验分享
Quartz学习总结 | Java技术经验分享
文章作者: LarsCheng · 2018-08-31 · via Java技术经验分享

Quartz学习总结

常规需求

  • 每天早上的闹钟
  • 定时统计数据

spring自带支持定时器的任务实现。其可通过简单配置来实现定时任务。

1
2
3
4
5
6
7
8
9
10
@Component
@Configurable
@EnableScheduling
public class ScheduledTasks{

@Scheduled(cron = "0 */1 * * * * ")
public void reportCurrentTimeByCorn(){
System.out.println("Cron北京时间:"+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS").format(new Date()));
}
}

但是当我们的业务需求发生变动,比如使用springboot自带的定时器发布的定时任务,在运行了一段时间后,我们想要修改他的执行时间,但又不能关闭项目,只能动态修改。怎么办呢???

Quartz任务调度框架,就可以解决这种烦恼。让你随意的修改和添加定时任务。

复杂需求

  • 暂停
  • 修改
  • 删除
  • 管理

当你在设计定时任务时,遇到了以上几种业务场景时,那么你就可以考虑使用quartz来解决,那么到底什么才是quartz呢?

完全由java开发的开源的任务日程管理系统,即在一个预先确定的时间到达时,负责执行或者通知其他软件组件的系统

springboot集成quartz小例子

我们可以先来看一个springboot中通过quartz实现定时任务的小栗子。

maven文件

注:springboot2.0以后就已经提供了quartz的依赖支持:spring-boot-starter-quartz,此处我们还是使用官方提供的依赖来举例。

1
2
3
4
5
6
7
8
9
10
<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>

创建一个Job

即定义一个任务类,实现Job接口,告诉quartz当任务任务的执行具体内容,创建SimpleJob类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.example.quartz.Job;

import org.quartz.*;
import java.util.Date;







public class SimpleJob implements Job {
public SimpleJob(){

}

@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {

System.out.println("开始执行简单任务"+new Date());
}
}

接着创建一个最基础的定时任务套路

QuartzDemo类,简单概括为5步,注意看代码注释

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package com.example.quartz.demo;

import com.example.quartz.Job.SimpleJob;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

import static org.quartz.SimpleScheduleBuilder.simpleSchedule;








public class QuartzDemo {
public static void main(String[] args) {

try {

Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();


scheduler.start();



JobDetail job = JobBuilder.newJob(SimpleJob.class)
.withIdentity("job1", "group1")
.build();


Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1", "group1")
.startNow()
.withSchedule(simpleSchedule()
.withIntervalInSeconds(6)
.withRepeatCount(10))
.build();


scheduler.scheduleJob(job, trigger);

} catch (SchedulerException e) {
e.printStackTrace();
}

}
}

运行QuartzDemo,观察控制台,你会发现一个简单的定时任务已经跑起来了!

Quartz中的要素:scheduler任务调度、Job任务、JobDetail任务详情、Trigger触发器

  • Job:任务的逻辑。通过实现Job接口,定义任务的执行内容,简单说就是定义“做什么?”
  • JobDetail:任务的定义,通过newJob()绑定Job类。描述自定义的Job实现类,比如任务的名字。另一方面也是为了防止并发问题,简单说就是定义“谁要做?”
  • Trigger:定时器,配置定时器的名称,配置定时器的类型触发方式等,简单说就是定义“什么时候做?”
  • Scheduler:调度器。接受一组JobDetail+Trigger即可安排一个任务,所有的调度由他控制

quartz的调度思路:

  1. 创建一个具体的任务(Job)
  2. 配置任务的触发时间等(Trigger)
  3. 配置任务的具体内容(JobDetail)
  4. 调度器Scheduled根据JobDetail+Trigger安排此任务去执行
    用一幅图简单形容一下quartz的原理

触发器种类

刚才的小例子中的触发器是以秒为时间间隔来定时调度,Quartz中有多种不同类型的触发器:

  • SimpleTrigger:用来存储方法只需用执行一次,或者时给定触发事件并重复执行N次并且每次执行延迟一定时间的任务。
  • CronTirgger:按照日历出发,例如每周五,每月十号十点钟,适合于更复杂的任务
  • DateIntervalTrigger:指定每天的某个时间段内,以一定的时间间隔执行任务。并且它可以支持指定星期。
  • CalendarIntervalTrigger:类似于SimpleTrigger,支持的间隔单位有秒,分钟,小时,天,月,年,星期。

quartz持久化方式

Quartz提供两种基本作业存储类型

  • 第一种类型叫做RAMJobStore
    • 最佳的性能,因为内存中数据访问最快
      不足之处是缺乏数据的持久性,当程序路途停止或系统崩溃时,所有运行的信息都会丢失
  • 第二种类型叫做JDBC作业存储
    • 通过调整其quartz.properties属性文件,持久化任务调度信息
      使用数据库保存任务调度信息后,即使系统崩溃后重新启动,任务的调度信息将得到恢复

quartz中其他知识点

通过阅读quartz的源码,以及官方的文档发现,quartz的开发者很喜欢用建造者模式。其实这种方式可以使复杂的对象更加清晰,阅读和使用中也更加清楚明了。

本文其实只是quartz的基础知识的学习和使用入门,springboot2.0之后也对quartz进行了封装,关于quartz更加优雅的使用方式和技巧也会在后面的博文中记录。