以下将分别从Quartz架构简介、集群部署实践、Quartz监控、集群原理分析详解Quartz任务调度框架。

Quartz简介

Quartz是Java领域最著名的开源任务调度工具,是一个任务调度框架,通过触发器设置作业的定时运行规则,来执行定时任务。其中quartz集群通过故障切换和负载平衡的功能,能给调度器带来高可用性和伸缩性。

Quartz提供了极为广泛的特性如持久化任务,集群和分布式任务等。

其特点如下:

  • 完全由Java写成,方便集成(Spring)
  • 伸缩性
  • 负载均衡
  • 高可用性

典型的使用场景,主要用来执行定时任务,例如:

  • 定时发送信息
  • 定时生成报表
  • 自动更新静态数据
  • 自动结账等等

Quartz架构简介

Quartz框架主要核心组件包括:

1.Scheduler任务调度

是最核心的概念,需要把JobDetail和Trigger注册到scheduler中,才可以执行。

工厂模式,组装各个组件<JOB,Trigger> sched.scheduleJob(job, trigger);

2.Job任务

其实Job是接口,其中只有一个execute方法,我们只需要 implements 此接口,重写 execute(*) 方法。

3.Trigger触发器

执行任务的规则;比如每天,每小时等。

一般情况使用SimpleTrigger,和CronTrigger,这些触发器实现了Trigger接口。或者 ScheduleBuilder 子类 SimpleScheduleBuilder和CronScheduleBuilder。

对于简单的时间来说,比如每天执行几次,使用SimpleTrigger。

对于复杂的时间表达式来说,比如每个月15日上午几点几分,使用CronTrigger以及CromExpression 类。

4.JobDetail任务细节

任务细节,Quartz执行Job时,需要新建个Job实例,但是不能直接操作Job类,所以通过JobDetail来获取Job的名称、描述信息。

调度器作为作业的总指挥,触发器作为作业的操作者,作业为应用的功能模块。

Quartz集群部署实践

Quartz与Spring结合使用,Spring通过提供org.springframework.scheduling.quartz下的封装类对Quartz支持。

1.Quartz集群部署:

Quartz集群中的每个节点是一个独立的Quartz应用,它又管理着其他的节点。该集群需要分别对每个节点分别启动或停止,不像应用服务器的集群,独立的Quartz节点并不与另一个节点或是管理节点通信。Quartz应用是通过数据库表来感知到另一应用。只有使用持久的JobStore才能完成Quqrtz集群。

基于Spring的集群配置:

  1. <!-- 调度工厂 -->
  2. <bean id="
  3. quartz
  4. Scheduler"
  5. class="org.springframework.scheduling.
  6. quartz
  7. .SchedulerFactoryBean">
  8. <property name="dataSource" ref="dataSource" />
  9. <property name="
  10. quartz
  11. Properties">
  12. <props>
  13. <prop key="org.
  14. quartz
  15. .scheduler.instanceName">CRMscheduler</prop>
  16. <prop key="org.quartz.scheduler.instanceId">AUTO</prop>
  17. <!-- 线程池配置 -->
  18. <prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop>
  19. <prop key="org.quartz.threadPool.threadCount">20</prop>
  20. <prop key="org.quartz.threadPool.threadPriority">5</prop>
  21. <!-- JobStore 配置 -->
  22. <prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
  23. <!-- 集群配置 -->
  24. <prop key="org.quartz.jobStore.isClustered">true</prop>
  25. <prop key="org.quartz.jobStore.clusterCheckinInterval">15000</prop>
  26. <prop key="org.quartz.jobStore.maxMisfiresToHandleAtATime">1</prop>
  27. <prop key="org.quartz.jobStore.misfireThreshold">120000</prop>
  28. <prop key="org.quartz.jobStore.tablePrefix">QRTZ_</prop>
  29. </props>
  30. </property>
  31. <property name="schedulerName" value="CRMscheduler" />
  32. <!--必须的,QuartzScheduler 延时启动,应用启动完后 QuartzScheduler 再启动 -->
  33. <property name="startupDelay" value="30" />
  34. <property name="applicationContextSchedulerContextKey" value="applicationContextKey" />
  35. <!--可选,QuartzScheduler 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了 -->
  36. <property name="overwriteExistingJobs" value="true" />
  37. <!-- 设置自动启动 -->
  38. <property name="autoStartup" value="true" />
  39. <!-- 注册触发器 -->
  40. <property name="triggers">
  41. <list>
  42. <ref bean="userSyncScannerTrigger" />
  43. ......
  44. </list>
  45. </property>
  46. <!-- 注册jobDetail -->
  47. <property name="jobDetails">
  48. <list>
  49. </list>
  50. </property>
  51. <property name="schedulerListeners">
  52. <list>
  53. <ref bean="quartzExceptionSchedulerListener" />
  54. </list>
  55. </property>
  56. </bean>
 org.quartz.jobStore.class属性为JobStoreTX,将任务持久化到数据中。因为集群中节点依赖于数据库来传播Scheduler实例的状态,你只能在使用JDBC JobStore时应用Quartz集群。 org.quartz.jobStore.isClustered属性为true,通知Scheduler实例要它参与到一个集群当中。 org.quartz.jobStore.clusterCheckinInterval属性定义了Scheduler实例检入到数据库中的频率(单位:毫秒)。Scheduler检查是否其他的实例到了它们应当检入的时候未检入;这能指出一个失败的Scheduler实例,且当前 Scheduler会以此来接管任何执行失败并可恢复的Job。通过检入操作,Scheduler 也会更新自身的状态记录。clusterChedkinInterval越小,Scheduler节点检查失败的Scheduler实例就越频繁。默认值是 15000 (即15 秒)。 其余参数在后文将会详细介绍。

Quartz监控

Quartz实例的监控、操作以及动态部署Trigger.

1.Triggers监控:

2.JobDetails监控:

Quartz集群原理分析

1. Quartz集群数据库表

Quartz的集群部署方案在架构上是分布式的,没有负责集中管理的节点,而是利用数据库锁的方式来实现集群环境下进行并发控制。BTW,分布式部署时需要保证各个节点的系统时间一致。

Quartz数据库核心表如下:

  • Table NameDescriptionQRTZ_CALENDARS存储Quartz的Calendar信息
  • QRTZ_CRON_TRIGGERS存储CronTrigger,包括Cron表达式和时区信息
  • QRTZ_FIRED_TRIGGERS存储与已触发的Trigger相关的状态信息,以及相联Job的执行信息
  • QRTZ_PAUSED_TRIGGER_GRPS存储已暂停的Trigger组的信息QRTZ_SCHEDULER_STATE

2. Quartz线程模型

在Quartz中有两类线程:

  • Scheduler调度线程
  • 任务执行线程

任务执行线程:Quartz不会在主线程(QuartzSchedulerThread)中处理用户的Job。

Quartz把线程管理的职责委托给ThreadPool,一般的设置使用SimpleThreadPool。SimpleThreadPool创建了一定数量的WorkerThread实例来使得Job能够在线程中进行处理。WorkerThread是定义在SimpleThreadPool类中的内部类,它实质上就是一个线程。例如,CRM中配置如下:

 <!-- 线程池配置 -->
<prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop>
<prop key="org.quartz.threadPool.threadCount">20</prop>
<prop key="org.quartz.threadPool.threadPriority">5</prop>

QuartzSchedulerThread调度主线程:QuartzScheduler被创建时创建一个QuartzSchedulerThread实例。

3.Quartz集群基于数据库锁的同步操作流程如下图所示:

一个调度器实例在执行涉及到分布式问题的数据库操作前,首先要获取QUARTZ_LOCKS表中对应的行级锁,获取锁后即可执行其他表中的数据库操作,随着操作事务的提交,行级锁被释放,供其他调度实例获取。集群中的每一个调度器实例都遵循这样一种严格的操作规程。

总结一下Quartz集群同步机制:每当要进行与某种业务相关的数据库操作时,先去QRTZ_LOCKS表中查询操作相关的业务对象所需要的锁,在select语句之后加for update来实现。例如,TRIGGER_ACCESS表示对任务触发器相关的信息进行修改、删除操作时所需要获得的锁。这时,执行查询这个表数据的SQL形如:

select * from QRTZ_LOCKS t where t.lock_name='TRIGGER_ACCESS' for update

当一个线程使用上述的SQL对表中的数据执行查询操作时,若查询结果中包含相关的行,数据库就对该行进行ROW LOCK;若此时,另外一个线程使用相同的SQL对表的数据进行查询,由于查询出的数据行已经被数据库锁住了,此时这个线程就只能等待,直到拥有该行锁的线程完成了相关的业务操作,执行了commit动作后,数据库才会释放了相关行的锁,这个线程才能继续执行。

通过这样的机制,在集群环境下,结合悲观锁的机制就可以防止一个线程对数据库数据的操作的结果被另外一个线程所覆盖,从而可以避免一些难以觉察的错误发生。当然,达到这种效果的前提是需要把Connection设置为手动提交,即autoCommit为false。

Quartz调度框架详解、运用场景、与集群部署实践的更多相关文章

  1. Redis详解(七)——集群

    Redis详解(七)--集群 ​Redis3.0版本之前,可以通过Redis Sentinel(哨兵)来实现高可用 ( HA ),从3.0版本之后,官方推出了Redis Cluster,它的主要用途是 ...

  2. Solr系列二:solr-部署详解(solr两种部署模式介绍、独立服务器模式详解、SolrCloud分布式集群模式详解)

    一.solr两种部署模式介绍 Standalone Server 独立服务器模式:适用于数据规模不大的场景 SolrCloud  分布式集群模式:适用于数据规模大,高可靠.高可用.高并发的场景 二.独 ...

  3. 详解k8s原生的集群监控方案(Heapster+InfluxDB+Grafana) - kubernetes

    1.浅析监控方案 heapster是一个监控计算.存储.网络等集群资源的工具,以k8s内置的cAdvisor作为数据源收集集群信息,并汇总出有价值的性能数据(Metrics):cpu.内存.netwo ...

  4. Zookeeper详解-伪分布式和集群搭建(八)

    说到分布式开发Zookeeper是必须了解和掌握的,分布式消息服务kafka .hbase 到hadoop等分布式大数据处理都会用到Zookeeper,所以在此将Zookeeper作为基础来讲解. Z ...

  5. Kafka 详解(二)------集群搭建

    这里通过 VMware ,我们安装了三台虚拟机,用来搭建 kafka集群,虚拟机网络地址如下: hostname                      ipaddress             ...

  6. 大数据入门第十六天——流式计算之storm详解(三)集群相关进阶

    一.集群提交任务流程分析 1.集群提交操作 参考:https://www.jianshu.com/p/6783f1ec2da0 2.任务分配与启动流程 参考:https://www.cnblogs.c ...

  7. Redis面试题详解:哨兵+复制+事务+集群+持久化等

    Redis主要有哪些功能? 1.哨兵(Sentinel)和复制(Replication) Redis服务器毫无征兆的罢工是个麻烦事,如何保证备份的机器是原始服务器的完整备份呢?这时候就需要哨兵和复制. ...

  8. 【59】Quartz+Spring框架详解

    什么是Quartz Quartz是一个作业调度系统(a job scheduling system),Quartz不但可以集成到其他的软件系统中,而且也可以独立运行的:在本文中"job sc ...

  9. Quartz.NET作业调度框架详解

    Quartz.NET作业调度框架详解 http://www.cnblogs.com/lmule/archive/2010/08/28/1811042.html

  10. mina框架详解

     转:http://blog.csdn.net/w13770269691/article/details/8614584 mina框架详解 分类: web2013-02-26 17:13 12651人 ...

随机推荐

  1. GitHub创建新仓库

    第一步.右上角点击[+],选择[New repository] 第二步.设置一下仓库的基本信息 在如下图的红框位置,输入仓库的名称.描述以及是否公开. 第三步.滑到最下面,点击[Create repo ...

  2. Wgpu图文详解(02)渲染管线与着色器

    在本系列的第一篇文章中(<Wgpu图文详解(01)窗口与基本渲染>),我们介绍了如何基于0.30+版本的winit搭建Wgpu的桌面环境,同时也讲解了关于Wgpu一些基本的概念.模块以及架 ...

  3. 使用expected_conditions的url_changes方法判断是否登录成功

    使用expected_conditions的url_changes方法判断是否跳转页面登录成功 from selenium import webdriver from selenium.webdriv ...

  4. Redis性能优化的18招

    前言 Redis在我们的日常开发工作中,使用频率非常高,已经变成了必不可少的技术之一. Redis的使用场景也很多. 比如:保存用户登录态,做限流,做分布式锁,做缓存提升数据访问速度等等. 那么问题来 ...

  5. git clone 远程代码执行漏洞(CVE-2024-32002) 升级

    接到提醒说git有个漏洞,Git clone 远程代码执行漏洞(CVE-2024-32002) 看了看,说是git的Symlinks模块存在高危漏洞,攻击者可以利用该漏洞执行任意代码,导致服务器失陷. ...

  6. 鸿蒙NEXT开发案例:数字转中文大小写

    [引言] 本应用的主要功能是将用户输入的数字转换为中文的小写.大写及大写金额形式.用户可以在输入框中输入任意数字,点击"示例"按钮可以快速填充预设的数字,点击"清空&qu ...

  7. 浅析Flie类getAbsolutePath()方法

    开发中,常常需要上传文件,并将文件存于远程服务器(如minio)或者本地,当存于本地时对存储路径的指定是常见的问题. 当然,你可以在本地写死静态资源路径,如"D:\static\fileUp ...

  8. Java深度历险(三)——Java线程​:基本概念、可见性与同步

    开发高性能并发应用不是一件容易的事情.这类应用的例子包括高性能Web服务器.游戏服务器和搜索引擎爬虫等.这样的应用可能需要同时处理成千上万个请求.对于这样的应用,一般采用多线程或事件驱动的架构.对于J ...

  9. 反编译工具之Jadx

    jadx 是一款功能强大的反编译工具,使用起来简单方便(拖拽式操作),不光提供了命令行程序,还提供了 GUI 程序.一般情况下,我们直接使用 GUI 程序就可以了. jadx 支持 Windows.L ...

  10. Windows之子系统WSL

    [安装] 安装参考:https://learn.microsoft.com/zh-cn/windows/wsl/install-manual#step-4---download-the-linux-k ...