任务调度之Quartz(二):Quartz体系结构

1、Quartz 体系结构

      由上一篇的Quartz基本使用可以发现,Quartz 主要包含一下几种角色:

            1)Job:也可以认为是JobDtetail,表示具体的调度任务

            2)Trigger:触发器,用于定义任务Job出发执行的规律

            3)Scheduler:调度器,用于将 JobDetail 和 Trigger绑定,并注册到容器中

            4)Listener:监听器,Quartz 中提供了3种监听器,即 JobListener、TriggerListener、

                                  SchedulerListener分别用来监听 Job、Trigger、Scheduler 的执行情况

            5)Jobstore:用来存储任务和触发器相关的信息

           如下图所示:

                  

            注意:

                    由上图可以发现,其中JobDetail是1对多(1:N)的关系,即一个JobDetail可以

                   去绑定多个触发器Trigger

      

2、JobDetail

     由Quartz基本使用笔记可以知道,在 Quartz 中Job需要通过JobBuilder 包装成JobDetail

     后才能被使用,具体用法请参考“Quartz基本使用”。

3、Trigger

      触发器 Trigger 通过Trigger Builder来构建,用于定义任务Job出发执行的规律。

      Trigger 在Quartz 中有4种子接口,分别是:

              

              1)SimpleTrigger:简单触发器,固定时刻或时间间隔触发,单位毫秒

                                   可以定义固定时刻或者固定时间间隔的调度规则(精确到毫秒)。

                                   例如:每天 9 点钟运行;每隔 30 分钟运行一次。

              2)CalendarIntervalTrigge:基于日历的触发器,单位秒,比简单触发器更多时间单位,

                                    支持非固定时间的触发,例如一 年可能 365/366,一个月可能 28/29/30/31

                                    好处是不需要去计算时间间隔,比如 1 个小时等于多少毫秒。

                                    每年的月数和每个月的天数不是固定的,这种情况也适用。   

              3)DailyTimeIntervalTrigger:基于日期的触发器,每天某个时间段触发,即每天的某

                                    个时间段内,以一定的时间间隔执行任务。

                                     例如:每天早上 9 点到晚上 9 点,每隔半个小时执行一次,并且只在

                                                周一到周六执行。

              4)CronTrigger:基于 Cron 表达式的触发器,可以定义基于 Cron 表达式的调度规则,

                                     是最常用的触发器类型。

      

3.1、Cron 表达式

         是一种用于指定定期执行任务的时间规则的字符串表达式。它由6或7个字段组成,

         每个字段代表不同的时间单位,包括秒、分、时、日、月、星期和年。

         Cron表达式通常以空格分隔这些字段,格式如下:

                 秒 分 时 日 月 星期 年

位置时间域特殊值
10-59, - * /
2分钟0-59, - * /
3小时0-23, - * /
4日期1-31, - * ? / L W C
5月份1-12, - * /
6星期1-7, - * ? / L W C
7年份(可选)1-31, - * /

        Cron 表达式特殊值含义:

         1)星号(*):可用在所有字段中,表示对应时间域的每一个时刻,

                             例如,在分钟字段时,表示“每分钟”;

         2)问号(?):该字符只在日期和星期字段中使用,它通常指定为“无意义的值”,

                                  相当于点(.)位符;

         3)减号(-):表达一个范围,如在小时字段中使用“10-12”,则表示从 10 到 12 点,

                              即 10,11,12;

         4)斜杠(/):x/y 表达一个等步长序列,x 为起始值,y 为增量步长值。

                           如:在分钟字段中使用 0/15,则表示为 0,15,30 和 45 秒,而 5/15 在分钟字段

                                 中表示 5,20,35,50,你也可以使用*/y,它等同于 0/y;

         5)L:该字符只在日期和星期字段中使用,代表“Last”的意思,但它在两个字段中意思不

                    同。L 在日期字段中,表示 这个月份的最后一天,如一月的 31 号,非闰年二月

                    的 28 号;如果 L 用在星期中,则表示星期六,等同于 7。但是,如果 L 出现在

                    星期字段里,而且在前面有一个数值 X,则表示“这个月的最后 X 天”,

                    例如:6L 表示该月的最后星期五;

         6)W:该字符只能出现在日期字段里,是对前导日期的修饰,表示离该日期最近的工作日。

                     例如 :15W 表示离该月 15号最近的工作日,如果该月 15 号是星期六,则匹配 14

                                 号星期五;如果 15 日是星期日,则匹配 16 号星期一;如果 15号是星期二,

                                  那结果就是 15 号星期二。但必须注意关联的匹配日期不能够跨月,如你指定

                                  1W,如果 1 号是星期六,结果匹配的是 3 号星期一,而非上个月最后的那

                                   天。W 字符串只能指定单一日期,而不能指定日期范围;

         7)LW 组合:在日期字段可以组合使用 LW,它的意思是当月的最后一个工作日;

         8)井号(#):该字符只能在星期字段中使用,表示当月某个工作日。

                             如 :6#3 表示当月的第三个星期五(6 表示星期五,#3 表示当前的第三个),而

                                    4#5 表示当月的第五个星期三,假设当月没有第五个星期三,忽略不触发;

         9)C:该字符只在日期和星期字段中使用,代表“Calendar”的意思。它的意思是计划所关联

                     的日期,如果日期没有被关联,则相当于日历中所有日期。

                      例如: 5C 在日期字段中就相当于日历 5 日以后的第一天。1C 在星期字段中相当于

                                  星期日后的第一天。

           注意:

                   Cron 表达式对特殊字符的大小写不敏感,对代表星期的缩写英文大小写也不敏感。

4、Scheduler

      调度器Scheduler 是Quartz的指挥官,由StdSchedulerFactory产生。它是单例的。

      Scheduler默认是实现类是StdScheduler,里面包含了一个QuartzScheduler,

      QuartzScheduler里面又包含了一个QuartzSchedulerThread。

      Scheduler中的方法主要分为三大类:

            1)操作调度器本身,例如调度器的启动start()、调度器的关闭shutdown()。

            2)操作Trigger,例如pauseTriggers()、resumeTrigger()。

            3)操作Job,例如scheduleJob()、unscheduleJob()、rescheduleJob()

        Scheduler 方法非常多,这里就不一一列举了。

5、Listener

      Quartz 中提供了3种监听器,即 JobListener、TriggerListener、SchedulerListener分

      别用来监听 Job、Trigger 和 Scheduler 的运行情况。

5.1、JobListener

         JobListener 主要用于监听 JobDetail(即Job) 在运行过程中是否有关键事件发生;

        这些关键事件包括:JobDetail是否被Trigger否决、JobDetail 是否执行完成等。

        JobListener 主要方法包括:

              1)getName():返回JobListener 的名称

              2)jobToBeExecuted():Scheduler 在 JobDetail 将要被执行时调用这个方法

              3)jobExecutionVetoed():Scheduler 在 JobDetail 即将被执行,但又被 TriggerListener

                           否决了时调用这个方法

              4)jobWasExecuted():Scheduler 在 JobDetail 被执行之后调用这个方法

5.2、TriggerListener

         TriggerListener 主要被用来监听触发器Trigger是否被触发,及触发后Job的execute 方法

         是否被执行。

         TriggerListener 常用方法如下:

                1)getName():返回监听器的名称

                2)triggerFired():Trigger 被触发,Job 上的 execute() 方法将要被执行时,Scheduler

                              就调用这个方法

                3)vetoJobExecution():在 Trigger 触发后,Job 将要被执行时由 Scheduler 调用这个

                              方法。TriggerListener 给了一个选择去否决 Job 的执行。假如这个方法返回

                              true,这个 Job 将不会为此次 Trigger 触发而得到执行

                4)triggerMisfired():Trigger 错过触发时调用

                5)triggerComplete():Trigger 被触发并且完成了 Job 的执行时,Scheduler 调用这个

                                方法

5.3、SchedulerListener

        SchedulerListener主要用于监控 Scheduler 的生命周期中是否有关键事件发生,

        当 Scheduler 有关键事件发生时 SchedulerListener 会被调用

        与Scheduler有关的事件包括:增加一个job/trigger,删除一个job/trigger,scheduler

        运行时发送错误,关闭scheduler等。

6、Jobstore

     Jobstore 主要用来存储任务和触发器相关的信息,例如所有任务的名称、数量、状态等等。

     Quartz中有两种存储任务的方式,一种在在内存,一种是在数据库。

6.1、RAMJobstore

      Quartz默认的JobStore是RAMJobstore,也就是把任务和触发器信息运行的信息存储在内

      存中,用到了HashMap、TreeSet、HashSet等等数据结构。

      如果程序崩溃或重启,所有存储在内存中的数据都会丢失。所以我们需要把这些数据持久化

      到磁盘或保存到数据库中。

6.2、JDBCJobStore

        JDBCJobStore可以通过JDBC接口,将任务运行数据保存在数据库中。

        JDBC的实现方式有两种,JobStoreSupport类的两个子类:

        JobStoreTX:在独立的程序中使用,自己管理事务,不参与外部事务。

        JobStoreCMT:(Container Managed Transactions (CMT),如果需要容器管理事务时

                             ,使用它。

         如下图所示:

                

        注意:

                使用JDBCJobSotre时,需要配置数据库信息并创建对应的表结构

                在quartz-jobsb包下,路径 src\org\quartz\impl\jdbcjobstore 下,Quartz

                提供了各种数据库的sql文件,直接拿来执行就行了,如下图所示:

                           

                           

                数据库配置如下:

                       在配置文件 quartz.properties 中配置 数据源信息,如下所示:    


 
/**
  JobStore持久化配置:将Quartz的数据保存到数据库中的配置
*/
org.quartz.jobStore.class:org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass:org.quartz.impl.jdbcjobstore.StdJDBCDelegate
# 使用quartz.properties,不使用默认配置
org.quartz.jobStore.useProperties:true
#数据库中quartz表的表名前缀
org.quartz.jobStore.tablePrefix:QRTZ_
org.quartz.jobStore.dataSource:myDS
 
#配置数据源
org.quartz.dataSource.myDS.driver:com.mysql.jdbc.Driver
org.quartz.dataSource.myDS.URL:jdbc:mysql://localhost:3306/quartz?useUnicode=true&characterEncoding=utf8
org.quartz.dataSource.myDS.user:root
org.quartz.dataSource.myDS.password:123456
org.quartz.dataSource.myDS.validationQuery=select 0 from dual


                         

               

quartz 需要的表名称与作用如下:

表名作用
QRTZ_BLOB_TRIGGERSTrigger作为Blob类型存储
QRTZ_CALENDARS存储Quartz的Calendar信息
QRTZ_CRON_TRIGGERS存储CronTrigger,包括Cron表达式和时区信息
QRTZ_FIRED_TRIGGERS存储与已触发的Trigger相关的状态信息,以及相关Job的执行信息
QRTZ_JOB_DETAILS存储每一个已配置的Job的详细信息
QRTZ_LOCKS存储程序的悲观锁的信息
QRTZ_PAUSED_TRIGGER_GRPS存储已暂停的Trigger组的信息
QRTZ_SCHEDULER_STATE存储少量的有关Scheduler的状态信息,和别的Scheduler实例
QRTZ_SIMPLE_TRIGGERS存储SimpleTrigger的信息,包括重复次数、间隔、以及已触的次数
QRTZ_SIMPROP_TRIGGERS存储CalendarIntervalTrigger和DailyTimeIntervalTrigger两种类型的触发器
QRTZ_TRIGGERS存储已配置的Trigger的信息

                

                 

        

                          

          

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/950102.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于Springboot + vue实现的小型养老院管理系统

🥂(❁◡❁)您的点赞👍➕评论📝➕收藏⭐是作者创作的最大动力🤞 💖📕🎉🔥 支持我:点赞👍收藏⭐️留言📝欢迎留言讨论 🔥🔥&…

初学Linux电源管理

学习文档出处: 万字整理 | 深入理解Linux电源管理:万字整理 | 深入理解Linux电源管理-CSDN博客 电源管理 因为设备需要用电,而且设备中的各个硬件所需要的电压是不一样的。故计算机需要对硬件的电源状态管理。但是电能并不是免费的&#x…

React(二)——Admin主页/Orders页面/Category页面

文章目录 项目地址一、侧边栏1.1 具体实现 二、Header2.1 实现 三、Orders页面3.1 分页和搜索3.2 点击箭头显示商家所有订单3.3 页码按钮以及分页 四、Category页面4.1 左侧商品添加栏目4.2 右侧商品上传栏 五、Sellers页面六、Payment Request 页面(百万数据加载&a…

刚体变换矩阵的逆

刚体运动中的变换矩阵为: 求得变换矩阵的逆矩阵为: opencv应用 cv::Mat R; cv::Mat t;R.t(), -R.t()*t

IDEA中Maven依赖包导入失败报红的潜在原因

在上网试了别人的八个问题总结之后依然没有解决&#xff1a; IDEA中Maven依赖包导入失败报红问题总结最有效8种解决方案_idea导入依赖还是报红-CSDN博客https://blog.csdn.net/qq_43705131/article/details/106165960 江郎才尽之后突然想到一个原因&#xff1a;<dep…

UVM:uvm_component methods configure

topic UVM component base class uvm_config_db 建议使用uvm_config_db代替uvm_resource_db uvm factory sv interface 建议&#xff1a;uvm_config_db 以下了解 建议打印error

基于时间维度水平拆分的多 TiDB 集群统一数据路由/联邦查询技术的实践

导读 在大数据时代&#xff0c;金融行业面临着日益增长的数据量和复杂的查询需求&#xff0c;尤其是跨库、跨集群的场景。在这种背景下&#xff0c;如何在保证数据一致性、高可用性的同时&#xff0c;实现业务的快速扩展与高效查询&#xff0c;成为了企业数字化转型的关键挑战…

概率论 期末 笔记

第一章 随机事件及其概率 利用“四大公式”求事件概率 加法公式 减法 条件概率公式 全概率公式与贝叶斯公式 伯努利概型求概率 习题 推导 一维随机变量及其分布 离散型随机变量&#xff08;R.V&#xff09;求分布律 利用常见离散型分布求概率 连续型R.V相关计算 利用常见连续…

把vue项目或者vue组件发布成npm包或者打包成lib库文件本地使用

将vue项目发布成npm库文件&#xff0c;第三方通过npm依赖安装使用&#xff1b;使用最近公司接了一个项目&#xff0c;这个项目需要集成到第三方页面&#xff0c;在第三方页面点击项目名称&#xff0c;页面变成我们的项目页面&#xff1b;要求以npm库文件提供给他们&#xff1b;…

《空舞的巨兽》官方学习版

一个以被遗忘之地为背景的原创故事&#xff0c;这是一个充满悲剧的没落王国。扮演外地战士雷恩猎人&#xff08;玩家&#xff09;&#xff0c;踏上危险的任务&#xff0c;结束困扰你自己和村庄的诅咒。你唯一的希望就是杀死不可杀死的可怕巨兽。 《空舞的巨兽》官方版 https:/…

go-zero框架快速入门

文章目录 go-zero 简介安装goctl安装go-zero启动go-zero API语言定义结构体API定义路由API格式化对齐 生成代码生成基本逻辑代码生成数据库model文件 go-zero 简介 go-zero 是一个集成了各种工程实践的 web 和 rpc 框架。通过弹性设计保障了大并发服务端的稳定性&#xff0c;经…

切忌 SELECT *,就算表只有一列

原文地址 尽量避免 SELECT *&#xff0c;即使在单列表上也是如此 – 如果你现在不同意这一点&#xff0c;读完这篇文章&#xff0c;你可能就要动摇了。 2012年的一个故事 这是我 12 年前&#xff08;约 2012-2013 年&#xff09;在客户后台应用程序中遇到的一个真实故事。 当…

了解RabbitMQ中的Exchange:深入解析与实践应用

在分布式系统设计中&#xff0c;消息队列&#xff08;Message Queue&#xff09;扮演着至关重要的角色&#xff0c;而RabbitMQ作为开源消息代理软件的佼佼者&#xff0c;以其高性能、高可用性和丰富的功能特性&#xff0c;成为了众多开发者的首选。在RabbitMQ的核心组件中&…

【linux系统之redis6】redis的基础命令使用及springboot连接redis

redis的基础命令很多&#xff0c;大部分我们都可以在官网上找到&#xff0c;真的用的时候可以去官网找&#xff0c;不用全部记住这些命令 redis通用的基础命令的使用 代码测试 string类型常见的命令 key值的结构&#xff0c;可以区分不同的需求不同的业务名字 hash类型 创建…

基于FPGA的交通信号灯实现 (verilog极简实现)

本文分享利用FPGA实现的交通信号灯&#xff0c;FPGA型号为野火征途Pro开发板&#xff0c;具体功能如下&#xff1a; 此项目旨在模拟东西和南北两路口交通信号灯&#xff0c;初始态两路口均为红灯亮&#xff0c;接着&#xff0c;东西路口绿灯亮&#xff0c;南北路口红灯亮&…

在K8S上部署OceanBase的最佳实践

在K8S上部署OceanBase的最佳实践 目录 1. 背景与选型 1.1 为什么选择OB1.2 为什么选择ob-operator实现OB on K8S 2. 部署实操 2.1 环境准备2.2 安装 ob-operator2.3 配置 OB 集群2.4 配置 OBProxy 集群2.5 Headless Service 和 CoreDNS 配置2.6 监控与运维 2.6.1 Promethues部…

unity开发之shader 管道介质流动特效

效果 shader graph 如果出现下面的效果&#xff0c;那是因为你模型的问题&#xff0c;建模做贴图的时候没有设置好UV映射&#xff0c;只需重新设置下映射即可

【JavaWeb】2. 通用基础代码

以下内容来源&#xff1a;编程导航。 无论在任何后端项目中&#xff0c;都可以复用的代码。 1、自定义异常 自定义错误码&#xff0c;对错误进行收敛&#xff0c;便于前端统一处理。 &#x1f4a1; 这里有 2 个小技巧&#xff1a; 自定义错误码时&#xff0c;建议跟主流的错…

Excel 技巧04 - 如何计算两个时间之差 (★)

本文讲了如何通过Excel计算两个时间的时间差。 1&#xff0c;计算两个时间的时间差 比如 5&#xff1a;50 ~ 19&#xff1a;40 a&#xff09;&#xff0c;用公式 相减 这样默认算出来的是机械的时间加减&#xff0c;即它们之间相差了 13小时50分钟 b&#xff09;&#xff0c;…