`
mengqingyu
  • 浏览: 333768 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

Quartz(三)原理及源码分析

 
阅读更多
quartz配置文件中可以通过以下两种配置读取方式
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore(从内存中读取定时任务)
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX(从数据库中读取定时任务)

以JobStoreTX为例,它最核心的组成部分是Scheduler、Trigger、JobDetail,然后给Scheduler配置个线程QuartzSchedulerThread,此线程在服务器启动时初始化Scheduler时启动,等待Scheduler start,然后从JobStore里拿到最近要触发的Trigger。
Scheduler:接口定义了对定时任务主要操作方法。
Trigger:定时器定义了任务执行时间。
JobDetail:定时任务一个JobDetail可以配置多个Trigger,主要定义了定时执行的类,方法,参数等信息。


任务定时执行:在服务器启动以后,每隔几秒至几十秒就会轮询StdJDBCDelegate类中selectTriggerToAcquire方法,执行sql查询qrtz_triggers表中NEXT_FIRE_TIME(下次触发时间)字段符合当前时间段并且TRIGGER_STATE状态为WAITING(等待中),符合此条件的Trigger查询出来,关联jobDetail来得到配置参数,调用配置好的业务方法。
	ps = conn.prepareStatement(rtp(SELECT_NEXT_TRIGGER_TO_ACQUIRE));
	
	// Try to give jdbc driver a hint to hopefully not pull over 
	// more than the few rows we actually need.
	ps.setFetchSize(5);
	ps.setMaxRows(5);
	
	ps.setString(1, STATE_WAITING);
	ps.setBigDecimal(2, new BigDecimal(String.valueOf(noLaterThan)));
	ps.setBigDecimal(3, new BigDecimal(String.valueOf(noEarlierThan)));
	rs = ps.executeQuery();
	
	while (rs.next() && nextTriggers.size() < 5) {
		nextTriggers.add(new Key(
				rs.getString(COL_TRIGGER_NAME),
				rs.getString(COL_TRIGGER_GROUP)));
	}
	
	return nextTriggers;


TRIGGER_STATE的更新:每次查找到匹配的Trigger,执行调度任务的同时,通过StdJDBCDelegate类的updateTriggerStateFromOtherState方法来更新TRIGGER_STATE状态为ACQUIRED(运行中),在执行完定时调度的业务方法时,将TRIGGER_STATE状态为WAITING(等待中)。
	ps = conn.prepareStatement(rtp(UPDATE_TRIGGER_STATE_FROM_STATES));
	ps.setString(1, newState);
	ps.setString(2, triggerName);
	ps.setString(3, groupName);
	ps.setString(4, oldState1);
	ps.setString(5, oldState2);
	ps.setString(6, oldState3);

	return ps.executeUpdate();

NEXT_FIRE_TIME的更新:在暂停、恢复任务状态或是每次时间轮询时都会判断NEXT_FIRE_TIME值是否小于当前时间,如果小于当前时间将永远不会执行,所以quartz会自动通过表达式来计算,参照当前时间来计算下次执行时间,执行updateTrigger方法更新NEXT_FIRE_TIME,或是每次查找到匹配的Trigger,执行调度任务的同时也会更新NEXT_FIRE_TIME下次运行时间。
    if(updateJobData) {
		ps = conn.prepareStatement(rtp(UPDATE_TRIGGER));
	} else {
		ps = conn.prepareStatement(rtp(UPDATE_TRIGGER_SKIP_DATA));
	}
		
	ps.setString(1, trigger.getJobName());
	ps.setString(2, trigger.getJobGroup());
	setBoolean(ps, 3, trigger.isVolatile());
	ps.setString(4, trigger.getDescription());
	long nextFireTime = -1;
	if (trigger.getNextFireTime() != null) {
		nextFireTime = trigger.getNextFireTime().getTime();
	}
	ps.setBigDecimal(5, new BigDecimal(String.valueOf(nextFireTime)));
	long prevFireTime = -1;
	if (trigger.getPreviousFireTime() != null) {
		prevFireTime = trigger.getPreviousFireTime().getTime();
	}
	ps.setBigDecimal(6, new BigDecimal(String.valueOf(prevFireTime)));
	ps.setString(7, state);
	if (trigger instanceof SimpleTrigger && ((SimpleTrigger)trigger).hasAdditionalProperties() == false ) {
		//                updateSimpleTrigger(conn, (SimpleTrigger)trigger);
		ps.setString(8, TTYPE_SIMPLE);
	} else if (trigger instanceof CronTrigger && ((CronTrigger)trigger).hasAdditionalProperties() == false ) {
		//                updateCronTrigger(conn, (CronTrigger)trigger);
		ps.setString(8, TTYPE_CRON);
	} else {
		//                updateBlobTrigger(conn, trigger);
		ps.setString(8, TTYPE_BLOB);
	}
	ps.setBigDecimal(9, new BigDecimal(String.valueOf(trigger
			.getStartTime().getTime())));	
	//代码略......

注意:在调试和测试quartz时,在局域网下如果没有做服务器集群,多个人启动了多台服务器,连接到同一台数据库服务器时会出现问题,因为quartz是多线程的,通过数据表记录来获得执行的任务,当多台服务器异步更新和读取的时候就会造成数据读取不同步问题,而出现bug。解决办法就是,测试时自己单独使用一个数据库,或是修改配置文件让其他人通过RAMJobStore读取,这样就不会造成多台机器同时读取一个库的问题发生了。
分享到:
评论

相关推荐

    Quartz.NET 官方源码及演示例子

    **源码分析** 1. **Quartz.build**:可能是构建脚本,用于构建整个项目,可能包含编译、测试和打包步骤。 2. **Quartz.2010.sln** 和 **Quartz.Server.2010.sln**:这是Visual Studio解决方案文件,用于打开和管理...

    quartz-1.4.5以及源码

    源码分析: 通过`quartz-1.4.5-sources.jar`,我们可以深入理解Quartz的内部工作原理。例如: - `org.quartz.Job`接口是所有任务类的基类,你需要实现它的execute方法来定义任务逻辑。 - `org.quartz.Trigger`接口...

    Quartz.NET 官方源码

    源码分析还可以帮助我们了解其事件机制,例如`SchedulerListener`和`JobListener`接口,它们允许用户在特定的调度或作业执行事件上进行自定义操作。 最后,Quartz.NET提供了丰富的API和配置选项,使得开发者可以...

    quartz1.6.0源码

    源码分析有助于深入理解其内部工作原理,从而更好地利用它来满足各种复杂的定时需求。Quartz 1.6.0源码包提供了一个宝贵的资源,帮助开发者探索其设计模式、线程管理以及任务调度的机制。 1. **Quartz核心概念** -...

    Quartz 开发指南(附源码)

    本指南将深入探讨 Quartz 的核心概念、配置与使用方法,并提供源码分析,帮助开发者更高效地利用这一强大工具。 1. **Quartz 基本概念** - **Job**:Job 是实际要执行的任务,是一个实现了 `org.quartz.Job` 接口...

    quartz源码解析(一)

    Quartz的源码分析可以从以下几个方面入手: 1. **设计模式**: - **工厂模式**:Quartz中Job和Trigger的创建主要通过SchedulerFactory和JobFactory,实现了对象的创建过程抽象化。 - **单例模式**:Scheduler通常...

    官方Quartz.NET 2.3.1 源码+15个示例

    开发者可以在这里查看并理解Quartz.NET的工作原理,甚至进行定制化开发。 2. `database`目录:可能包含与数据库相关的脚本或配置,如SQL脚本用于创建Quartz.NET需要的表结构。Quartz.NET支持多种数据库,如MySQL、...

    quartz-3.0.3.1_quartes_源码.zip

    这个压缩包 "quartz-3.0.3.1_quartes_源码.zip" 包含了 Quartz 框架的源代码,版本为 3.0.3.1,对于学习和理解 Quartz 的工作原理以及进行定制化开发非常有帮助。 Quartz 主要功能包括: 1. **作业调度**:Quartz ...

    Quartz.NET-2.2 源码

    Quartz.NET-2.2源码提供了对这个版本的全部源代码,让开发者能够深入理解其工作原理并进行自定义扩展。 在提供的文件列表中,我们可以看到以下几个关键文件和目录: 1. **Quartz.build**: 这是构建脚本,通常包含...

    quartz-2.1.7 官方jar包源码

    源码分析对于理解Quartz的工作原理至关重要。在Quartz-2.1.7源码中,你可以看到如下关键组件: 1. `org.quartz.core` 包:这是Quartz的核心模块,包含Scheduler、JobStore和ThreadPool的主要实现。SchedulerImpl是...

    quartz定时器源码jar包下载

    Quartz是一款开源的作业调度框架,它为Java应用程序提供了强大的定时任务管理能力。作为一个专业的IT行业大师,我很高兴为你解析...源码中的注释将有助于你更好地理解Quartz的工作原理。祝你在学习过程中收获满满!

    quartz-master.zip

    源码分析: 1. **Job接口**:Job是所有任务的基础,它定义了`execute`方法,这是任务实际执行的地方。开发者可以创建自己的Job类,实现这个接口,然后在Scheduler中注册。 2. **Trigger接口**:Trigger接口及其...

    Quartz-1.8.4官方

    6. **源码分析**:对于开发者来说,拥有源码意味着可以深入了解Quartz的工作机制,遇到问题时能够直接查看源码找到解决方案,或者根据需求进行定制开发。 7. **示例项目**:官方提供的示例代码可以帮助开发者快速...

    IOS应用源码——QuartzDemo.rar

    QuartzDemo是一个针对iOS平台的源码示例项目,它主要展示了如何使用Quartz 2D...通过分析和学习这些代码,开发者能够深入理解Quartz 2D的工作原理,并将其应用到自己的iOS项目中,创造出更加丰富的用户界面和图形效果。

    quartz动态任务管理

    学习和理解这个源码包,可以帮助你深入理解Quartz的工作原理,以及如何在实际项目中灵活运用。通过分析和实践,你可以掌握如何创建动态任务,如何根据业务需求调整任务执行策略,以及如何进行错误处理和监控。这将对...

    quartz helloworld例子

    5. **源码分析** "quartz_test"可能包含了一个简单的Quartz应用示例,可能包含了上述的Job类、配置文件、主程序等。通过对源码的分析,你可以更好地理解Quartz的工作原理,例如如何定义触发规则、如何传递参数、...

    xxl job源码分析

    xxl-job是一个轻量级的任务调度平台,具备开源特性,其源码分析对于工程开发人员具有一定的参考价值。接下来,我们将详细介绍xxl-job的核心概念、架构特点以及源码分析过程中的关键知识点。 首先,xxl-job项目的...

    spring2与quartz在Web整合

    2. **Quartz 工作原理**:Quartz 是基于 JDBC 或内存的数据存储方式来管理作业和触发器的。它通过 Scheduler 接口来调度作业,作业是需要执行的任务,触发器则定义了作业的执行时间或频率。Quartz 还支持 Cron ...

    quartz2.2.1 spring3.1.1

    Quartz 2.2.1 和 Spring 3.1.1 是两个在企业级Java应用开发中常用的开源框架。Quartz 是一个强大的、...通过源码分析,开发者可以更好地理解这两个框架的内部机制,从而更有效地利用它们的功能来满足特定的业务需求。

Global site tag (gtag.js) - Google Analytics