实现quartz定时器及用quartz做集群的定时任务
来源:互联网 发布:网络维护外包费用 编辑:程序博客网 时间:2024/06/08 22:18
由于工作需要,我要写一个定时器,每天定时执行的定时任务。现在分享给大家。
本文将会围绕
核心概念。
简单的入门实例。
项目中遇到的问题。
以及解决方案。
最后的总结。
给大家介绍。
一、核心概念
1、Job
表示一个工作,要执行的具体内容。此接口中只有一个方法
void execute(JobExecutionContext context)
2、JobDetail
JobDetail表示一个具体的可执行的调度程序,Job是这个可执行程调度程序所要执行的内容,另外JobDetail还包含了这个任务调度的方案和策略。
3、Trigger代表一个调度参数的配置,什么时候去调。
4、Scheduler代表一个调度容器,一个调度容器中可以注册多个JobDetail和Trigger。当Trigger与JobDetail组合,就可以被Scheduler容器调度了。
二、一个最简单入门实例
代码如下:
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import java.util.Date;
/**
* quartz定时器测试
*
* @author leizhimin 2009-7-23 8:49:01
*/
public class MyJob implements Job {
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println(new Date() + ": doing something...");
}
}
class Test {
public static void main(String[] args) {
//1、创建JobDetial对象
JobDetail jobDetail = new JobDetail();
//设置工作项
jobDetail.setJobClass(MyJob.class);
jobDetail.setName("MyJob_1");
jobDetail.setGroup("JobGroup_1");
//2、创建Trigger对象
SimpleTrigger strigger = new SimpleTrigger();
strigger.setName("Trigger_1");
strigger.setGroup("Trigger_Group_1");
strigger.setStartTime(new Date());
//设置重复停止时间,并销毁该Trigger对象
java.util.Calendar c = java.util.Calendar.getInstance();
c.setTimeInMillis(System.currentTimeMillis() + 1000 * 1L);
strigger.setEndTime(c.getTime());
strigger.setFireInstanceId("Trigger_1_id_001");
//设置重复间隔时间
strigger.setRepeatInterval(1000 * 1L);
//设置重复执行次数
strigger.setRepeatCount(3);
//3、创建Scheduler对象,并配置JobDetail和Trigger对象
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler scheduler = null;
try {
scheduler = sf.getScheduler();
scheduler.scheduleJob(jobDetail, strigger);
//4、并执行启动、关闭等操作
scheduler.start();
} catch (SchedulerException e) {
e.printStackTrace();
}
// try {
// //关闭调度器
// scheduler.shutdown(true);
// } catch (SchedulerException e) {
// e.printStackTrace();
// }
}
}
从这里也可以看出,scheduler是个容器,scheduler控制jobDetail的执行,控制的策略是通过trigger。
当scheduler容器启动后,jobDetail才能根据关联的trigger策略去执行。当scheduler容器关闭后,所有的jobDetail都停止执行。
三、项目中遇到的问题
Spring自带的Task虽然能很好使用定时任务,只需要做些简单的配置就可以了。不过如果部署在多台服务器上的时候,这样定时任务会在每台服务器都会执行,造成重复执行。
四、解决方案
Spring+quartz 集群可以解决多服务器部署定时器重复执行的问题。
1、下载quartz的Jar包或者在Maven项目加入quartz的依赖包
1、log4j-1.2.16
2、quartz-2.1.7
3、slf4j-api-1.6.1.jar
4、slf4j-log4j12-1.6.1.jar
2、建立quartz表
quartz是通过表来实现多服务器定时任务集群的,表的详细信息在压缩包:quartz-2.2.3-distribution.tar.gz,
路径为:quartz-2.2.3-distribution\quartz-2.2.3\docs\dbTables
这里有很多表的SQL可执行语句,直接复制执行即可。
3、新增一个Bean文件(spring-quartz.xml),如下:
Xml代码
xml version="1.0" encoding="UTF-8"
beans xmlns="http://www.springfr amework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springfr amework.org/schema/beans http://www.springfr amework.org/schema/beans/spring-beans.xsd"
<!-- 配置任务bean类 -->
bean id="quartzTask" class="com.lqy.spring.task.QuartzTask"bean
<!-- 配置方法映射工厂类 -->
<!-- MethodInvokingJobDetailFactoryBean不支持序列化 -->
<!-- bean id="jobDetail" class="org.springfr amework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"
property name="targetObject" ref="quartzTask"property
property name="targetMethod" value="startTask"property
property name="concurrent" value="false"property
concurrent : false表示等上一个任务执行完后再开启新的任务
bean --
<!-- 配置方法映射工厂类 -->
bean id="jobDetail" class="org.springfr amework.scheduling.quartz.JobDetailFactoryBean"
property name="jobClass" value="com.lqy.spring.task.QuartzTaskExtends"property
property name="durability" value="true"property
property name="requestsRecovery" value="true"
bean
<!-- 配置任务高度的的时间/周期 -->
bean id="jobTrigger" class="org.springfr amework.scheduling.quartz.CronTriggerFactoryBean"
property name="jobDetail" ref="jobDetail"property
property name="cronex pression" value="0 */1 * * * ?"property
<!-- <property name="startDelay" value="3000"></property> -->
bean
bean id="schedulerFactoryBean" class="org.springfr amework.scheduling.quartz.SchedulerFactoryBean"
property name="dataSource" ref="dataSource"property
<!--可选,QuartzScheduler 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了 -->
property name="overwriteExistingJobs" value="true"
<!--必须的,QuartzScheduler 延时启动,应用启动完后 QuartzScheduler 再启动 -->
property name="startupDelay" value="30"
<!-- 设置自动启动 -->
property name="autoStartup" value="true"
property name="applicationContextSchedulerContextKey" value="applicationContextKey"
property name="configLocation" value="classpath:spring-quartz.properties"
property name="triggers"
list
ref bean="jobTrigger"
list
property
bean
beans
spring-quartz.xml文件里面主要配置的是定时任务
4、把上面的spring-quartz.xml 引入到spring.xml文件中
Xml代码
import resource="spring-quartz.xml"
5、把项目部署到集群环境中
其实就是把项目部署到2个Tomcat中,这样能看到定时任务是否重复执行。
6、启动所有Tomcat,看结果。
总结:
1、搞清楚了上Quartz容器执行作业的的原理和过程,以及作业形成的方式,作业注册到容器的方法。就认识明白了Quartz的核心原理。
2、Quartz虽然很庞大,但是一切都围绕这个核心转,为了配置强大时间调度策略,可以研究专门的CronTrigger。要想灵活配置作业和容器属性,可以通过Quartz的properties文件或者XML来实现。
3、要想调度更多的持久化、结构化作业,可以通过数据库读取作业,然后放到容器中执行。
4、所有的一切都围绕这个核心原理转,搞明白这个了,再去研究更高级用法就容易多了。
5、Quartz与Spring的整合也非常简单,Spring提供一组Bean来支持:MethodInvokingJobDetailFactoryBean、SimpleTriggerBean、SchedulerFactoryBean,看看里面需要注入什么属性即可明白了。Spring会在Spring容器启动时候,启动Quartz容器。
6、Quartz容器的关闭方式也很简单,如果是Spring整合,则有两种方法,一种是关闭Spring容器,一种是获取到SchedulerFactoryBean实例,然后调用一个shutdown就搞定了。如果是Quartz独立使用,则直接调用scheduler.shutdown(true);
7、Quartz的JobDetail、Trigger都可以在运行时重新设置,并且在下次调用时候起作用。这就为动态作业的实现提供了依据。你可以将调度时间策略存放到数据库,然后通过数据库数据来设定Trigger,这样就能产生动态的调度。
- 实现quartz定时器及用quartz做集群的定时任务
- java spring-quartz定时器实现定时任务
- Spring+quartz实现定时任务集群
- 用Quartz实现定时任务
- Quartz实现定时任务
- Quartz实现定时任务
- quartz实现定时任务
- quartz实现定时任务
- quartz实现定时任务
- Quartz实现定时任务
- Quartz实现定时任务
- spring quartz 实现定时任务及常见问题
- quartz的定时任务
- Spring集成Quartz定时器实现定时作业任务
- Java定时器(二)之Spring定时任务、Quartz实现
- quartz java实现的定时任务框架
- springmvc+quartz定时任务的实现
- QuartZ--Spring中定时任务的实现
- 主流JS框架技术站点收集
- git学习笔记整理-5-撤销提交
- String StringBuilder StringBuffer
- Simple Monitor Dubbo监控中心部署与使用
- 游戏服务器的登陆框架
- 实现quartz定时器及用quartz做集群的定时任务
- AJAX POST&跨域 解决方案
- python数据分析实践(四)
- 【LeetCode】1. Two Sum
- @Scheduled+BlockingQueue实现异步接口
- HDU-2017 多校训练赛5-1008-Rikka with Subset
- Unity [属性] 常用
- zabbix 连接oracle数据库问题
- 以太坊私有链创建及智能合约的部署和交互