<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    paulwong

    分布式調度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;


    參考:
    http://wenku.baidu.com/view/82e3bcbdfd0a79563c1e7223.html

    Quartz集成springMVC 的方案二(持久化任務、集群和分布式)
    http://blog.csdn.net/congcong68/article/details/39256307















    posted on 2014-11-14 18:46 paulwong 閱讀(14921) 評論(0)  編輯  收藏 所屬分類: J2EE分布式

    主站蜘蛛池模板: 国产午夜亚洲精品国产| 四虎影视在线看免费观看| 手机在线毛片免费播放| 无码色偷偷亚洲国内自拍| 亚洲日韩涩涩成人午夜私人影院| 成人片黄网站色大片免费观看APP| 亚洲宅男永久在线| 天天看免费高清影视| 久久国产福利免费| 亚洲一区二区三区亚瑟| 免费乱理伦在线播放| 免费污视频在线观看| 亚洲狠狠婷婷综合久久蜜芽| 在线观看亚洲av每日更新 | 免费可以在线看A∨网站| 又粗又长又爽又长黄免费视频| 亚洲欧洲一区二区| 成人免费无码精品国产电影| 国偷自产一区二区免费视频| 亚洲国产精品成人综合色在线| 亚洲午夜无码久久久久| 最近免费中文字幕大全| 51午夜精品免费视频| 亚洲人精品亚洲人成在线| 亚洲国产一成人久久精品| 免费涩涩在线视频网| 亚洲免费精彩视频在线观看| 羞羞漫画页面免费入口欢迎你| 亚洲欧洲精品在线| 久久精品国产亚洲沈樵| 全部免费国产潢色一级| 免费观看激色视频网站bd| 国产无遮挡又黄又爽免费网站| 黑人粗长大战亚洲女2021国产精品成人免费视频| 亚洲色中文字幕无码AV| 四虎1515hm免费国产| 少妇高潮太爽了在线观看免费| 午夜精品免费在线观看 | 久久精品无码精品免费专区| 国产精品成人亚洲| 77777亚洲午夜久久多喷|