分布式调度QUARTZ+SPRING

使用SPRING的定时任务框架,如果是在分布式的环境下,由于有多台节点,会产生相同的任务,会被多个节点执行,这时需引入分布式的QUARTZ。

触发器:存放时间排程

任务:蔟业务代码

排程器:负责调度,即在指定的时间执行对应的任务

如果是分布式QUARTZ,则各个节点会上报任务,存到数据库中,执行时会从数据库中取出触发器来执行,如果触发器的名称和执行时间相同,则只有一个节点去执行此任务。

如果此节点执行失败,则此任务则会被分派到另一节点执行。

quartz.properties

#
============================================================================

#
 Configure JobStore

#
 Using Spring datasource in quartzJobsConfig.xml

#
 Spring uses LocalDataSourceJobStore extension of JobStoreCMT

#
============================================================================

org.quartz.jobStore.useProperties=true

org.quartz.jobStore.tablePrefix = QRTZ_

org.quartz.jobStore.isClustered = true

org.quartz.jobStore.clusterCheckinInterval = 5000

org.quartz.jobStore.misfireThreshold = 60000

org.quartz.jobStore.txIsolationLevelReadCommitted = true

#
 Change this to match your DB vendor

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

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

#
============================================================================

#
 Configure Main Scheduler Properties

#
 Needed to manage cluster instances

#
============================================================================

org.quartz.scheduler.instanceId=AUTO

org.quartz.scheduler.instanceName=MY_CLUSTERED_JOB_SCHEDULER

org.quartz.scheduler.rmi.export = false

org.quartz.scheduler.rmi.proxy = false

#
============================================================================

#
 Configure ThreadPool

#
============================================================================

org.quartz.threadPool.
class = org.quartz.simpl.SimpleThreadPool

org.quartz.threadPool.threadCount = 10

org.quartz.threadPool.threadPriority = 5

org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true

web-schedule-applicationcontext.xml

<?
xml version="1.0" encoding="UTF-8"
?>

<
beans 
xmlns
="http://www.springframework.org/schema/beans"

xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:context
="http://www.springframework.org/schema/context"

xmlns:mongo
="http://www.springframework.org/schema/data/mongo"

xsi:schemaLocation
="http://www.springframework.org/schema/context
          http://www.springframework.org/schema/context/spring-context-3.0.xsd
          http://www.springframework.org/schema/data/mongo
          http://www.springframework.org/schema/data/mongo/spring-mongo-1.3.xsd
          http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
>

<!--
 增加定时器配置 
-->

<!--
 线程执行器配置,用于任务注册 
-->

<
bean 
id
="executor"
 class
="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"
>

<
property 
name
="corePoolSize"
 value
="10"
 
/>

<
property 
name
="maxPoolSize"
 value
="100"
 
/>

<
property 
name
="queueCapacity"
 value
="500"
 
/>

</
bean
>

<!--
 设置调度 
-->

<
bean 
id
="webScheduler"

class
="org.springframework.scheduling.quartz.SchedulerFactoryBean"
>

<
property 
name
="configLocation"
 value
="classpath:/properties/config/quartz.properties"
 
/>

<
property 
name
="dataSource"
 ref
="dataSourceCMS"
 
/>

<
property 
name
="transactionManager"
 ref
="txManager"
 
/>

<!--
 This name is persisted as SCHED_NAME in db. for local testing could 
            change to unique name to avoid collision with dev server 
-->

<
property 
name
="schedulerName"
 value
="quartzScheduler"
 
/>

<!--
 Will update database cron triggers to what is in this jobs file on 
            each deploy. Replaces all previous trigger and job data that was in the database. 
            YMMV 
-->

<
property 
name
="overwriteExistingJobs"
 value
="true"
 
/>

<
property 
name
="startupDelay"
 value
="5"
/>

<
property 
name
="applicationContextSchedulerContextKey"
 value
="applicationContext"
 
/>

<
property 
name
="jobFactory"
>

<
bean 
class
="com.tcl.project7.boss.common.scheduling.AutowiringSpringBeanJobFactory"
 
/>

</
property
>

<
property 
name
="triggers"
>

<
list
>

<
ref 
bean
="springQuertzClusterTaskSchedulerTesterTigger"
 
/>

</
list
>

</
property
>

<
property 
name
="jobDetails"
>

<
list
>

<
ref 
bean
="springQuertzClusterTaskSchedulerTesterJobDetail"
 
/>

</
list
>

</
property
>

<
property 
name
="taskExecutor"
 ref
="executor"
 
/>

</
bean
>

<!--
 触发器 
-->

<
bean 
id
="springQuertzClusterTaskSchedulerTesterTigger"
 class
="common.scheduling.PersistableCronTriggerFactoryBean"
>

<
property 
name
="jobDetail"
 ref
="springQuertzClusterTaskSchedulerTesterJobDetail"
/>

<
property 
name
="cronExpression"
 value
="* * * * * ?"
 
/>

</
bean
>

<
bean 
id
="springQuertzClusterTaskSchedulerTesterJobDetail"
 class
="org.springframework.scheduling.quartz.JobDetailBean"
>

<
property 
name
="jobClass"
 value
="common.scheduling.SpringQuertzClusterTaskSchedulerTester"
 
/>

<!--
 fail-over 重写执行失败的任务,default=false 
-->

<
property 
name
="requestsRecovery"
 value
="false"
/>

</
bean
>

</
beans
>

JOB文件:SpringQuertzClusterTaskSchedulerTester.java

package common.scheduling;

import java.util.Date;

import org.quartz.JobExecutionContext;

import org.quartz.JobExecutionException;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.scheduling.quartz.QuartzJobBean;

import com.tcl.project7.boss.common.util.UrlUtil;

import com.tcl.project7.boss.common.util.time.TimeUtils;

/**

* <p>Title:SpringQuertzClusterTaskSchedulerTester</p>
 * <p>Description:
 * 应为要持久化等特性操作,需要继承 QuartzJobBean
 * <br>由于要被持久化,所以不能存放xxxxManager类似对象,
 * 只能从每次从QuartzJobBean注入的ApplicationContext 中去取出
 *
 * </p>    
 *
 *
 
*/

public 
class SpringQuertzClusterTaskSchedulerTester 
extends QuartzJobBean {

private 
static Logger logger = LoggerFactory.getLogger(SpringQuertzClusterTaskSchedulerTester.
class);

@Autowired

private UrlUtil urlUtil;

protected 
void executeInternal(JobExecutionContext arg0)

throws JobExecutionException {

logger.info("------" + TimeUtils.formatTime(
new Date()) + "------" + urlUtil.getNginxHost());

System.out.println("------" + TimeUtils.formatTime(
new Date()) + "------" + urlUtil.getNginxHost());

}

}

如果JOB中有需要调用SPRING的BEAN,则需要此文件AutowiringSpringBeanJobFactory.java

package common.scheduling;

import org.quartz.spi.TriggerFiredBundle;

import org.springframework.beans.factory.config.AutowireCapableBeanFactory;

import org.springframework.context.ApplicationContext;

import org.springframework.context.ApplicationContextAware;

import org.springframework.scheduling.quartz.SpringBeanJobFactory;

/**

* Autowire Quartz Jobs with Spring context dependencies
 * 
@see
 
http://stackoverflow.com/questions/6990767/inject-bean-reference-into-a-quartz-job-in-spring/15211030
#15211030
 
*/

public 
final 
class AutowiringSpringBeanJobFactory 
extends SpringBeanJobFactory 
implements ApplicationContextAware {

private 
transient AutowireCapableBeanFactory beanFactory;

public 
void setApplicationContext(
final ApplicationContext context) {

beanFactory = context.getAutowireCapableBeanFactory();

}

@Override

protected Object createJobInstance(
final TriggerFiredBundle bundle) 
throws Exception {

final Object job = 
super.createJobInstance(bundle);

beanFactory.autowireBean(job);

return job;

}

}

由于JOB需要存储到数据库中,会产生PROPERTY的问题,需剔除JOB-DATA,需此文件PersistableCronTriggerFactoryBean.java

package common.scheduling;

import org.springframework.scheduling.quartz.CronTriggerFactoryBean;

import org.springframework.scheduling.quartz.JobDetailAwareTrigger;

/**

* Needed to set Quartz useProperties=true when using Spring classes,
 * because Spring sets an object reference on JobDataMap that is not a String
 * 
 * 
@see
 
http://site.trimplement.com/using-spring-and-quartz-with-jobstore-properties/


@see
 
http://forum.springsource.org/showthread.php?130984-Quartz-error-IOException

*/

public 
class PersistableCronTriggerFactoryBean 
extends CronTriggerFactoryBean {

@Override

public 
void afterPropertiesSet() {

super.afterPropertiesSet();

//
Remove the JobDetail element

getJobDataMap().remove(JobDetailAwareTrigger.JOB_DETAIL_KEY);

}

}

建表语句,MYSQL:quartzTables.sql

#

# Quartz seems 
to 
work best 
with the driver mm.mysql
-
2.0.
7
-bin.jar

#


In your Quartz properties 
file, you

ll need to set 
# org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#

DROP TABLE IF EXISTS QRTZ_JOB_LISTENERS;
DROP TABLE IF EXISTS QRTZ_TRIGGER_LISTENERS;
DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
DROP TABLE IF EXISTS QRTZ_LOCKS;
DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
DROP TABLE IF EXISTS QRTZ_CALENDARS;

CREATE TABLE QRTZ_JOB_DETAILS
  (
    JOB_NAME  VARCHAR(200) NOT NULL,
    JOB_GROUP VARCHAR(200) NOT NULL,
    DESCRIPTION VARCHAR(250) NULL,
    JOB_CLASS_NAME   VARCHAR(250) NOT NULL,
    IS_DURABLE VARCHAR(1) NOT NULL,
    IS_VOLATILE VARCHAR(1) NOT NULL,
    IS_STATEFUL VARCHAR(1) NOT NULL,
    REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
    JOB_DATA BLOB NULL,
    PRIMARY KEY (JOB_NAME,JOB_GROUP)
);

CREATE TABLE QRTZ_JOB_LISTENERS
  (
    JOB_NAME  VARCHAR(200) NOT NULL,
    JOB_GROUP VARCHAR(200) NOT NULL,
    JOB_LISTENER VARCHAR(200) NOT NULL,
    PRIMARY KEY (JOB_NAME,JOB_GROUP,JOB_LISTENER),
    FOREIGN KEY (JOB_NAME,JOB_GROUP)
        REFERENCES QRTZ_JOB_DETAILS(JOB_NAME,JOB_GROUP)
);

CREATE TABLE QRTZ_TRIGGERS
  (
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    JOB_NAME  VARCHAR(200) NOT NULL,
    JOB_GROUP VARCHAR(200) NOT NULL,
    IS_VOLATILE VARCHAR(1) NOT NULL,
    DESCRIPTION VARCHAR(250) NULL,
    NEXT_FIRE_TIME BIGINT(13) NULL,
    PREV_FIRE_TIME BIGINT(13) NULL,
    PRIORITY INTEGER NULL,
    TRIGGER_STATE VARCHAR(16) NOT NULL,
    TRIGGER_TYPE VARCHAR(8) NOT NULL,
    START_TIME BIGINT(13) NOT NULL,
    END_TIME BIGINT(13) NULL,
    CALENDAR_NAME VARCHAR(200) NULL,
    MISFIRE_INSTR SMALLINT(2) NULL,
    JOB_DATA BLOB NULL,
    PRIMARY KEY (TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (JOB_NAME,JOB_GROUP)
        REFERENCES QRTZ_JOB_DETAILS(JOB_NAME,JOB_GROUP)
);

CREATE TABLE QRTZ_SIMPLE_TRIGGERS
  (
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    REPEAT_COUNT BIGINT(7) NOT NULL,
    REPEAT_INTERVAL BIGINT(12) NOT NULL,
    TIMES_TRIGGERED BIGINT(10) NOT NULL,
    PRIMARY KEY (TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (TRIGGER_NAME,TRIGGER_GROUP)
        REFERENCES QRTZ_TRIGGERS(TRIGGER_NAME,TRIGGER_GROUP)
);

CREATE TABLE QRTZ_CRON_TRIGGERS
  (
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    CRON_EXPRESSION VARCHAR(200) NOT NULL,
    TIME_ZONE_ID VARCHAR(80),
    PRIMARY KEY (TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (TRIGGER_NAME,TRIGGER_GROUP)
        REFERENCES QRTZ_TRIGGERS(TRIGGER_NAME,TRIGGER_GROUP)
);

CREATE TABLE QRTZ_BLOB_TRIGGERS
  (
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    BLOB_DATA BLOB NULL,
    PRIMARY KEY (TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (TRIGGER_NAME,TRIGGER_GROUP)
        REFERENCES QRTZ_TRIGGERS(TRIGGER_NAME,TRIGGER_GROUP)
);

CREATE TABLE QRTZ_TRIGGER_LISTENERS
  (
    TRIGGER_NAME  VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    TRIGGER_LISTENER VARCHAR(200) NOT NULL,
    PRIMARY KEY (TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_LISTENER),
    FOREIGN KEY (TRIGGER_NAME,TRIGGER_GROUP)
        REFERENCES QRTZ_TRIGGERS(TRIGGER_NAME,TRIGGER_GROUP)
);

CREATE TABLE QRTZ_CALENDARS
  (
    CALENDAR_NAME  VARCHAR(200) NOT NULL,
    CALENDAR BLOB NOT NULL,
    PRIMARY KEY (CALENDAR_NAME)
);

CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS
  (
    TRIGGER_GROUP  VARCHAR(200) NOT NULL, 
    PRIMARY KEY (TRIGGER_GROUP)
);

CREATE TABLE QRTZ_FIRED_TRIGGERS
  (
    ENTRY_ID VARCHAR(95) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    IS_VOLATILE VARCHAR(1) NOT NULL,
    INSTANCE_NAME VARCHAR(200) NOT NULL,
    FIRED_TIME BIGINT(13) NOT NULL,
    PRIORITY INTEGER NOT NULL,
    STATE VARCHAR(16) NOT NULL,
    JOB_NAME VARCHAR(200) NULL,
    JOB_GROUP VARCHAR(200) NULL,
    IS_STATEFUL VARCHAR(1) NULL,
    REQUESTS_RECOVERY VARCHAR(1) NULL,
    PRIMARY KEY (ENTRY_ID)
);

CREATE TABLE QRTZ_SCHEDULER_STATE
  (
    INSTANCE_NAME VARCHAR(200) NOT NULL,
    LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
    CHECKIN_INTERVAL BIGINT(13) NOT NULL,
    PRIMARY KEY (INSTANCE_NAME)
);

CREATE TABLE QRTZ_LOCKS
  (
    LOCK_NAME  VARCHAR(40) NOT NULL, 
    PRIMARY KEY (LOCK_NAME)
);

INSERT INTO QRTZ_LOCKS values(
‘TRIGGER_ACCESS

);
INSERT INTO QRTZ_LOCKS values(
‘JOB_ACCESS

);
INSERT INTO QRTZ_LOCKS values(
‘CALENDAR_ACCESS

);
INSERT INTO QRTZ_LOCKS values(
‘STATE_ACCESS

);
INSERT INTO QRTZ_LOCKS values(
‘MISFIRE_ACCESS

);

commit;

时间: 2024-10-26 00:37:12

分布式调度QUARTZ+SPRING的相关文章

详解应对平台高并发的分布式调度框架TBSchedule

tbschedule是一款非常优秀的高性能分布式调度框架,非常高兴能分享给大家.这篇文章是我结合多年tbschedule使用经验和研读三遍源码的基础上完成的,期间和阿里空玄有过不少技术交流,非常感谢空玄给予的大力支持.我写这篇文章的目的一是出于对tbschedule的一种热爱,二是现在是一个资源共享.技术共享的时代,希望把它展现给大家(送人玫瑰,手留余香),能给大家的工作带来帮助. 一.tbschedule初识 时下互联网和电商领域,各个平台都存在大数据.高并发的特点,对数据处理的要求越来越高,

我的物联网项目(八)简单分布式调度

定时调度基本在任何平台或多或少的要用到,实现定时调度的功能很简单,我做过的项目中用到更多的是spring quartz或者spring task,它们在单机上使用定时任务配置是非常简单的,但是在集群环境中就需要面临一个必须解决的问题:如何限定只有一台机器在执行定时任务? 其实spring quartz也可以实现此功能,它是由数据库的数据来确定调度任务是否正在执行, 正在执行则其他服务器就不能去执行该行调度数据,所以需要数据库的11张表来执行此种功能,总的来说成本较高,操作起来也比较复杂.另外一些

定时任务的分布式调度

转自:https://www.cnblogs.com/haoxinyue/p/6886196.html 单机定式任务调度的问题 在很多应用系统中我们常常要定时执行一些任务.比如,订单系统的超时状态判断.缓存数据的定时更新.定式给用户发邮件,甚至是一些定期计算的报表等等.常见的处理方式有线程的while(true) 和sleep组合.使用Timer定时器触发任务又或者是使用quartz框架.貌似这些方法可以完美的解决方案,为什么还需要分布式呢?主要有如下两点原因: 1.高可用:单机版的定式任务调度

quartz+spring 实现多任务动态定时器问题

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <beans xmlns="http://www.springframework.org/schema/beans"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"   

quartz spring配置实例代码demo下载

原文:quartz spring配置实例代码demo下载 源代码下载地址:http://www.zuidaima.com/share/1550463459560448.htm

分布式调度

分布式调度两大任务: 任务调度:大量计算任务.任务如何切分.数据如何分割.运算.监控运算状态. 资源调度 1.任务调度 2.资源调度 3.容错机制 4.规模挑战 5.安全与性能隔离 6.分布式调度发展方向 在VLDB 2014 Fuxi论文 http://www.vldb.org/pvldb/vol7/p1393-zhang.pdf 原文地址:https://www.cnblogs.com/jiweilearn/p/8908277.html

Quartz Spring分布式集群搭建Demo

注:关于单节点的Quartz使用在这里不做详细介绍,直接进阶为分布式集群版的 1.准备工作: 使用环境Spring4.3.5,Quartz2.2.3,持久化框架JDBCTemplate pom文件如下 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="h

Spring进阶-怎样集成定时调度Quartz

在一些项目里面比如进销存系统,对一些过期图片的定时清理或者库存不足发出预警提示,就需要用到定时调度技术. 每当经过一段时间,程序会自动执行,就是定时调度.如果要使用定时调度,则必须保证程序始终运行才行哦,也就是说定时调度是在程序之外又启动了一个新的线程.那么怎样才能实现定时调度呢? 方案一:可以使用JDK自带的java.util.Timer对象.可以创建定制的timer或者调用某些方法的timer.包装timer的工作由Spring TimerFactoryBean完成,不过这种方法不能准确设置

【59】Quartz+Spring框架详解

什么是Quartz Quartz是一个作业调度系统(a job scheduling system),Quartz不但可以集成到其他的软件系统中,而且也可以独立运行的:在本文中"job scheduler"的意思是:一个负责在约定的时间到达时执行(或通知)其他软件控件的方法. Quartz是非常灵活的,为了实现我们的需求Quartz包含了许多可以独立或被集成使用的典型范例,同时使我们编写项目中的代码也觉得很简单自然(natural). Quartz是很轻量级的,只需要简单的安装或配置就