最佳实践:利用Quartz实现任务调度的集群

软件体系最佳实践文档

第 1 页 共 10 页

最佳实践:利用Quartz实现任务调度的集群

分类:JAVA

作者:凡彬勇

日期:2012-06-20

导读:Quartz集群的实现

1. 任务调度为什么要实现集群

公众企业应用几乎都会碰到任务调度的需求,任务调度本身涉及到多线程并发、运行时间规则制定和解析、场景保持与恢复、线程池维护等诸多方面的工作。如果直接使用自定义线程这种刀耕火种的原始办法,开发任务调度程序是一项颇具挑战性的工作。Java开源的好处就是:领域问题都能找到现成的解决方案。

OpenSymphony所提供的Quartz自2001年发布版本以来已经被众多项目作为任务调度的解决方案,Quartz在提供巨大灵活性的同时并未牺牲其简单性,它所提供的强大功能使你可以应付绝大多数的调度需求。Quartz 在开源任务调度框架中的翘首,它提供了强大任务调度机制,难能可贵的是它同时保持了使用的简单性。Quartz 允许开发人员灵活地定义触发器的调度时间表,并可以对触发器和任务进行关联映射。此外,Quartz提供了调度运行环境的持久化机制,可以保存并恢复调度现场,即使系统因故障关闭,任务调度现场数据并不会丢失。此外,Quartz还提供了组件式的侦听器、各种插件、线程池等功能。

2. quartz集群的原理

一个 Quartz 集群中的每个节点是一个独立的 Quartz 应用,它又管理着其他的节点。意思是你必须对每个节点分别启动或停止。不像许多应用服务器的集群,独立的 Quartz 节点并不与另一其的节点或是管理节点通信。Quartz 应用是通过数据库表来感知到另一应用的。 软件体系最佳实践文档

第 2 页 共 10 页

图:表示了每个节点直接与数据库通信,若离开数据库将对其他节点一无所知

集群通过故障切换和负载平衡的功能,能给调度器带来高可用性和伸缩性。目前集群只能工作在JDBC- Jobstore (JobStoreTX 或者JobStoreCMT)方式下,从本质上来说,是使集群上的每一个节点通过共享同一个数据库来工作的(Quartz通过启动两个维护线程来维护数据库状态实现集群管理,一个是检测节点状态线程,一个是恢复任务线程)。负载平衡是自动完成的,集群的每个节点会尽快触发任务。当一个触发器的触发时间到达时,第一个节点将会获得任务(通过锁定),成为执行任务的节点。故障切换的发生是在当一个节点正在执行一个或者多个任务失败的时候。当一个节点失败了,其他的节点会检测到并且标识在失败节点上正在进行的数据库中的任务。任何被标记为可恢复(任务详细信息的"requests recovery"属性)的任务都会被其他的节点重新执行。没有标记可恢复的任务只会被释放出来,将会在下次相关触发器触发时执行

3. quartz集群步骤

3.1. 创建Quartz数据库表

因为Quartz 集群依赖于数据库,所以必须首先创建Quartz数据库表。Quartz 包括了所有被支持的数据库平台的 SQL 脚本。在

/docs/dbTables 目录下找到那些 SQL 脚本,这里的

是解压 Quartz 分发包后的目录。

这里采用的Quartz 1.8.5版本,总共12张表,不同版本,表个数可能不同。数据库为oracle,用tables_oracle.sql创建数据库表。 软件体系最佳实践文档

第 3 页 共 10 页

3.2. 配置数据库连接池 ,这里使用Spring+C3p0

在系统的全局配置文件中新增如下信息,我这里的全局配置文件是:config.properties

db.dialect=org.hibernate.dialect.Oracle9Dialect

db.driverClassName=oracle.jdbc.driver.OracleDriver

db.url=jdbc:oracle:thin:@127.0.0.1:1521:feelview

ername=feelviewdata

db.password=paic1234

TescronExpression1=0 0/1 * ? * *

其中:TescronExpression1是定时器的crontab表达式(我这里配置的是每分钟跑一次),下面在配置CronTriggerBean的时候会使用到。关于crontab表达式的配置这里不做介绍,在quartz的官方文档有详细介绍

class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

classpath:config.properties

class="boPooledDataSource"

destroy-method="close">

5 软件体系最佳实践文档

第 4 页 共 10 页

30

10

60

5

0

name="idleConnectionTestPeriod">60

30

true

false

3.3. 创建Job测试服务类

创建job接口,注意,因为Job需要持久化到数据库中,Job必须实现Serializable接口

public interface IJob extends Serializable{

/**

* 处理任务的核心函数

*

* @param cxt Spring 上下文

*/

void executeInternal();

}

合集下载

quartz.net任务调度分布式,动态添加(1)

quartz.net任务调度分布式,动态添加(1)

任务调度分布式,动态添加(1)

try

{

//1.⾸先创建⼀个作业调度池

var properties = new NameValueCollection();

properties["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool, Quartz";

properties["quartz.threadPool.threadCount"] = "10";

properties["quartz.threadPool.threadPriority"] = "Normal";

//存储类型

properties["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz";

//驱动类型

properties["quartz.jobStore.driverDelegateType"] = "Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz"; //数据源名称

properties["quartz.jobStore.dataSource"] = "myDS";

//连接字符串

properties["quartz.dataSource.myDS.connectionString"] = @"server=.;Initial Catalog=quartz;Integrated Security=True";

//sqlserver版本

properties["quartz.dataSource.myDS.provider"] = "SqlServer-20";

//是否集群

properties["quartz.jobStore.clustered"] = "true";

properties["quartz.scheduler.instanceId"] = "AUTO";

quartz用法

quartz用法

Quartz用法

一、什么是Quartz?

Quartz是一个功能强大且广泛应用于Java中的开源任务调度框架。它允许开发人员通过简单而灵活的方式在应用程序中调度和执行任务。无论是简单的定时任务还是复杂的作业调度,Quartz都可以满足需求。

二、Quartz的基本概念

在深入探讨Quartz的用法之前,我们首先需要了解一些基本概念。

1. 作业(Job)

作业是Quartz中最基本的调度单元。它表示一项任务或一个操作,可以被Quartz调度和执行。

2. 触发器(Trigger)

触发器是Quartz中用于指定作业何时执行的组件。可以根据时间表达式(如每小时、每天等)来触发作业的执行,也可以根据特定的日期和时间来触发。

3. 调度器(Scheduler)

调度器是Quartz的核心组件,它负责在指定的时间触发作业的执行。调度器可以同时管理多个作业和触发器,并根据设定的调度策略来决定执行顺序。

三、Quartz的用法

接下来,我们将深入探讨Quartz的用法,包括作业和触发器的创建、调度器的配置和管理。 1. 创建作业

要创建一个作业,我们需要定义一个类,实现Quartz的Job接口,并重写其中的execute()方法。在execute()方法中,我们可以编写具体的任务逻辑。例如:

public class MyJob implements Job {

public void execute(JobExecutionContext context) throws JobExecutionException {

// 编写具体的任务逻辑

}

}

2. 创建触发器

Quartz提供了多种触发器类型,可以根据需求灵活选择。其中最常用的是SimpleTrigger和CronTrigger。

• SimpleTrigger:简单触发器会在指定的时间间隔内循环执行作业。可以设置作业的开始时间、结束时间和重复次数。

Quartz实现任务调度表达式说明

Quartz实现任务调度表达式说明

Quartz实现任务调度表达式说明

在特殊时间执⾏某次操作 使⽤CronTrigger

CronTrigger也是Trigger的⼦类

CronTrigger和SimpleTrigger的对⽐:

CronTrigger允许⽤户更精准地控制任务的运⾏⽇期和时间,⽽不仅仅是定义⼯作的频度

CronTrigger通过Cron表达式定义准确的运⾏时间点。创建CronTrigger的语法如下:

四、Cron表达式 要使⽤CronTrigger,必须掌握Cron表达式

Cron表达式由6~7个由空格分隔的时间元素组成。第7个元素可选

Cron表达式有⼏个特殊的字符,说明如下:

Cron表达式案例:⽰例:

quartz-scheduler 分布式原理

quartz-scheduler 分布式原理

quartz-scheduler 分布式原理

Quartz Scheduler是一个开源的作业调度器,旨在实现可靠、稳定的作业调度。作为分布式系统的一部分,它提供了分布式任务调度的功能。Quartz Scheduler采用了一些核心原理来支持分布式任务调度,其中包括集群支持、数据存储方式、数据库锁机制以及任务触发器的机制等。

首先,Quartz Scheduler的分布式机制在于集群支持。集群支持允许多个Quartz Scheduler节点在一个共享的数据库中运行,这就提供了任务调度器的高可用性和负载均衡的能力。每个节点都可以独立地获取数据库中的作业,然后执行任务。节点之间通过数据库同步来实现任务状态的同步。当一个节点挂掉时,其他节点可以接管它的任务,并继续执行。

其次,Quartz Scheduler使用数据库作为任务存储方式。它提供了多个数据库表来存储作业、触发器、调度器等相关信息。这样的设计使得多个节点之间能够共享任务信息,并保持一致性。在集群模式下,每个节点都可以独立地从数据库中获取作业,因此,任务信息的一致性是非常重要的。

为了保持任务信息的一致性,Quartz Scheduler采用了数据库锁机制,避免多个节点同时执行同一个任务。当一个节点获取到任务后,它会通过数据库锁机制锁定任务,阻止其他节点获取同一个任务。这样可以确保每个任务只被执行一次,避免了冲突和重复执行的问题。

此外,Quartz Scheduler还提供了多种触发器的机制来支持任务的调度。常见的触发器包括简单触发器和Cron触发器。简单触发器允许我们指定任务的执行时间、执行次数和执行间隔,而Cron触发器允许我们通过Cron表达式来指定任务的执行时间。分布式任务调度器需要保证不同节点之间的触发器的一致性,确保任务在集群中按照预期的触发时间和次数执行。

在分布式环境中,节点之间的通信和协调也是实现分布式任务调度的关键。Quartz Scheduler使用了一些机制来实现节点之间的通信和协调,例如使用数据库表作为节点之间的通信媒介,通过数据库的变更通知机制,一个节点可以感知到另一个节点的变更并做出相应的响应。另外,Quartz Scheduler还提供了对节点的监控和管理接口,允许我们实时监控和管理任务的执行情况。

quartz集群防止多个实例重复执行原理

quartz集群防止多个实例重复执行原理

Quartz集裙是一个非常强大的任务调度框架,它可以让我们方便地管理和调度任务。在Quartz集裙中,我们经常会遇到一个问题,就是多个实例重复执行任务的情况。这种情况会导致一些严重的后果,比如数据不一致,任务执行效率低下等问题。我们需要一些机制来避免多个实例同时执行同一个任务。本文将介绍Quartz集裙是如何防止多个实例重复执行的原理。

1. 分布式锁

Quartz集裙防止多个实例重复执行的原理之一就是使用分布式锁。当有任务需要执行时,Quartz集裙中的每一个实例会尝试获取一个全局的锁。只有成功获取锁的实例才能执行任务,其他实例则需要等待锁释放后再次尝试获取。这样就能确保同一个任务只有一个实例在执行,避免了多个实例重复执行的问题。

2. 数据库乐观锁

除了分布式锁之外,Quartz集裙还可以使用数据库的乐观锁来实现防止多个实例重复执行任务。在数据库中,每一个任务会有一个版本号字段。当任务需要执行时,Quartz集裙的每一个实例都会尝试更新任务的版本号字段。只有成功更新版本号的实例才能执行任务,其他实例则需要放弃执行。通过版本号字段的更新,可以确保同一个任务只有一个实例在执行,从而避免了多个实例重复执行的问题。

3. 心跳检测

除了分布式锁和数据库乐观锁之外,Quartz集裙还可以通过心跳检测的方式来防止多个实例重复执行任务。每一个Quartz实例都会定时向Quartz集裙中的其他实例发送心跳包。当一个实例需要执行任务时,它会先发送一个“我要执行任务”的消息给其他实例。其他实例收到消息后,会立刻知道有一个实例要执行任务,然后放弃自己的执行计划。通过心跳检测,可以确保同一个任务只有一个实例在执行,避免了多个实例重复执行的问题。

总结

Quartz集裙防止多个实例重复执行的原理主要包括分布式锁、数据库乐观锁和心跳检测。通过这些机制,我们可以确保同一个任务只有一个实例在执行,避免了多个实例重复执行的问题。在实际应用中,我们可以根据自己的需求选择合适的机制来避免多个实例重复执行任务,确保任务调度的准确性和高效性。对于Quartz集裙防止多个实例重复执行的原理,我们还可以进一步探讨其在实际应用中的具体实现和优化策略。以下是Quartz集裙防止多个实例重复执行的原理的进一步扩展和实践经验。

Quartz学习笔记:集群部署高可用

Quartz学习笔记:集群部署高可用

Quartz学习笔记:集群部署⾼可⽤Quartz学习笔记:集群部署&⾼可⽤

集群部署

⼀个Quartz集群中的每个节点是⼀个独⽴的Quartz应⽤,它⼜管理着其他的节点。这就意味着你必须对每个节点分别启动或停⽌。Quartz集群中,独

⽴的Quartz节点并不与另⼀其的节点或是管理节点通信,⽽是通过同⼀个数据库表来感知到另⼀Quartz应⽤的。

因为Quartz集群依赖于数据库,所以必须⾸先创建Quartz数据库表,Quartz发布包中包括了所有被⽀持的数据库平台的SQL脚本。这些SQL脚本存放

于/docs/dbTables ⽬录下。不同版本,表个数可能不同。

集群配置

创建完表结构之后,我们需要配置Quartz,以让其感知⾃⼰是集群的⼀份⼦。定义quartz.properties配置⽂件默认放在应⽤classpath路径下,其他路

径只能⾃⼰⼿动加载properties。下⾯是集群配置参考:

#集群中应⽤采⽤相同的Scheduler实例

org.quartz.scheduler.instanceName: wenqyScheduler

#集群节点的ID必须唯⼀,可由quartz⾃动⽣成

org.quartz.scheduler.instanceId: AUTO

#通知Scheduler实例要它参与到⼀个集群当中

org.quartz.jobStore.isClustered: true

#需持久化存储

org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX

org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate

#数据源

org.quartz.jobStore.dataSource=myDS

#quartz表前缀

org.quartz.jobStore.tablePrefix=QRTZ_

使用SpringBoot2.X实现Quartz动态任务的分布式调度

使用SpringBoot2.X实现Quartz动态任务的分布式调度

小Hub领读:

常见的分布式定时任务框架:elastic-job、xxl-job、quartz ,你都熟悉吗,今天先来学一下Quartz吧!

作者:Sam Sho见名知意,该篇番外主要是要解决如下几个问题:1、使用 SpringBoot2.x 版本集成 Quartz2、Quartz 的任务动态实现:调度任务可以通过页面进行新增、删除、启动、暂定等操作

任务数据使用数据库保存

任务之间实现简单的依赖3、Quartz 实现分布式调度,使用其本身提供的基于数据库的实现SpringBoot2 集成 Quartz

1、SpringBoot 不同的版本对于 Quartz 的集成有一定的差别,本文使用 2.1.2.RELEASE 版本。其实通过分析 SpringBoot对于 Quartz 的自动化配置源码,也有助于我们理解 Quartz 的使用2、SpringBoot-2.1.2.RELEASE 版本已经集成了对于 Quartz 的自动化配置,其源码路径为 org.springframework.boot.autoconfigure.quartz集成简单实现

Pom 依赖

1. # Web工程

2.

3. org.springframework.boot

4. spring-boot-starter-web

5.

6.

7. # quartz

8.

9. org.springframework.boot

10. spring-boot-starter-quartz

11.

12.

13. # 数据库JDBC

14.

15. org.springframework.boot

16. spring-boot-starter-jdbc17.

18.

19. # 使用MySql

20.

21. mysql

22. mysql-connector-java

23. runtime

24.

编码功能实现

quartz 调度原理

quartz 调度原理

Quartz是一个开源的调度框架,用于在Java应用程序中实现定时任务和周期性任务。Quartz提供了简单易用的API,使得开发者可以轻松地创建、调度和管理任务。本篇文章将介绍Quartz的调度原理,帮助开发者更好地理解和使用Quartz。

Quartz调度器是Quartz框架的核心组件,它负责管理任务的调度和执行。调度器通过创建一个Job和一个Trigger来表示一个任务及其执行时间。Job是要执行的任务类,Trigger是表示任务执行时间的触发器。调度器根据触发器的定义,在指定的时间点或周期性执行Job。

二、任务调度原理

Quartz调度器通过时间轴来管理任务。时间轴是一个有序的集合,包含了所有待执行的任务及其执行时间。调度器按照时间轴的顺序依次执行任务,确保每个任务按照预定时间执行。

Quartz调度器采用了基于时间的触发器模型,它可以根据时间间隔、固定时间、周期性执行等方式来触发任务的执行。触发器与任务的关系通过Trigger对象来表示,调度器根据Trigger对象在时间轴上标记任务的执行时间。

当触发器到达预定时间时,调度器会触发任务的执行。调度器会创建一个新的JobExecutionListener,用于监听任务的执行过程,并在任务执行完成后进行相应的处理。

三、调度器配置

使用Quartz调度框架需要配置相关的参数和数据源。开发者可以通过配置文件或编程方式来设置调度器的属性,如任务执行的间隔时间、周期性任务的执行方式等。同时,开发者还需要提供Job类和Trigger对象,用于描述要执行的任务及其执行时间。

Quartz调度框架还提供了丰富的API,方便开发者进行任务的管理和操作。开发者可以通过API来添加、删除、修改任务,以及查询任务执行的状态和结果。

四、总结

Quartz调度框架是一个功能强大、易于使用的任务调度工具,它可以帮助开发者轻松地实现定时任务和周期性任务的调度。通过了解Quartz的调度原理和配置方法,开发者可以更好地理解和使用Quartz,提高应用程序的性能和可靠性。

浅析Quartz的集群配置(二)

浅析Quartz的集群配置(二)

基本信息

摘要:Quartz是一个开源的作业调度框架,它完全由java写成,并设计用于J2SE和J2EE应用中。它提供了巨大的灵活性而不牺牲简单性。你能够用它来为执行一个作业而创建简单的或复杂的调度。它有很多特征,如:数据库支持,集群,插件,EJB作业预构建,JavaMail及其它,支持cron-like表达式等等。其中集群配置一般比较复杂,那么在Quartz中如何配置它的集群特性呢?

作者:武玉厚

查看本文第一部分:

3.1.2.3 任务存储(JobStore)的配置

1. #

2. # 定义一个任务存储的一般模式如下:

3. # 4. # org.quartz.jobStore.class =

org.quartz.simpl.RAMJobStore

5. # org.quartz.jobStore.misfireThreshold =

MISFIRE_THRESHOLD

6. #

7. # or

8. #

9. # org.quartz.jobStore.class =

org.quartz.impl.jdbcjobstore.

10. # JobStoreClass 是下面其中的一个:

11. # - JobStoreTX 用于单机(standalone-Quartz)实现

12. # - JobStoreCMT 用于基于应用服务器容器管理事务(appserver-based container-managed transaction )的Quartz

实现

13. #

14. # org.quartz.jobStore.driverDelegateClass =

org.quartz.impl.jdbcjobstore.

15. # DriverDelegateClass 是下面其中的一个:

16. # - StdJDBCDelegate (用于许多 JDBC-compliant drivers)

通过源码分析Java开源任务调度框架Quartz的主要流程

通过源码分析Java开源任务调度框架Quartz的主要流程

通过源码分析Java开源任务调度框架Quartz的主要流程

从使⽤效果、调⽤链路跟踪、E-R图、循环调度逻辑⼏个⽅⾯分析Quartz。

github项⽬地址: , 补充了SQL输出

系统说明:

IDE: IntelliJ

JDK:1.8

Quartz:2.2.1

使⽤效果

1.从github项⽬中,拉取项⽬到本地,导⼊IDEA。

相信读者都有⼀定⼯作经验,这些细节不赘述。

2.本⽂采⽤Mysql数据库。

请执⾏ resources/scripts/tables_mysql_innodb.sql

3.修改jdbc.properties中数据库配置

4.通过IDEA, Edit Configurations -> Add Tomcat Server, 部署到Tomcat

暴露的Restful 接⼝ /say-hello.do 以及添加好任务后的调⽤效果:

添加任务

在tomcat启动成功后,在⾸页点击“添加任务”,添加如下任务:

代码执⾏逻辑在SyncJobFactory类中,从Output中可以看到执⾏的输出信息,

调⽤链跟踪的最后会回到这个类来。

现在开始跟踪调⽤链路。

IDEA 快捷键:

进⼊⽅法: Ctrl + ⿏标左键

光标前进/后退: Ctrl + Shirt + 右⽅向键/左⽅向键

⼀、 调⽤链路跟踪

从配置⽂件applicationContext.xml配置中找到任务调度核⼼类SchedulerFactoryBean

resources/applicationContext.xml

...

使⽤IDEA快捷键,点击进⼊SchedulerFactoryBean类,它实现了InitializingBean接⼝,

在Spring中凡是实现了InitializingBean接⼝的Bean,都会在Bean属性都设置完成后调⽤afterPropertiesSet()⽅法.

SchedulerFactoryBean.java

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档