`
shenhaiyue
  • 浏览: 25798 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Quartz集成springMVC (持久化任务、集群和分布式)

    博客分类:
  • java
 
阅读更多

Quartz是一个开放源码项目,专注于任务调度器,提供了极为广泛的特性如持久化任务,集群和分布式任务等。 Quartz核心是调度器,还采用多线程管理。

 

1.持久化任务:当应用程序停止运行时,所有调度信息不被丢失,当你重新启动时,调度信息还存在,这就是持久化任务。

 

2.集群和分布式处理:当在集群环境下,当有配置Quartz的多个客户端时(节点),采用Quartz的集群和分布式处理时,我们要了解几点好处 1) 一个节点无法完成的任务,会被集群中拥有相同的任务的节点取代执行。2) Quartz调度是通过触发器的类别来识别不同的任务,在不同的节点定义相同的触发器的类别,这样在集群下能稳定的运行,一个节点无法完成的任务,会被集群中拥有相同的任务的节点取代执行。3分布式 体现在 当相同的任务定时在一个时间点,在那个时间点,不会被两个节点同时执行。

 

 Quartz的 Task11 张表)实例化采用数据库存储,基于数据库引擎及 High-Available 的策略(集群的一种策略)自动协调每个节点的 Quartz

 

 

 

[sql] view plain copy
 
  1.    
  2. delete from qrtz_fired_triggers;  
  3. delete from qrtz_simple_triggers;  
  4. delete from qrtz_simprop_triggers;  
  5. delete from qrtz_cron_triggers;  
  6. delete from qrtz_blob_triggers;  
  7. delete from qrtz_triggers;  
  8. delete from qrtz_job_details;  
  9. delete from qrtz_calendars;  
  10. delete from qrtz_paused_trigger_grps;  
  11. delete from qrtz_locks;  
  12. delete from qrtz_scheduler_state;  
  13.    
  14.    
  15.    
  16. CREATE TABLE qrtz_job_details  
  17.   (  
  18.     SCHED_NAME VARCHAR2(120) NOT NULL,  
  19.     JOB_NAME  VARCHAR2(200) NOT NULL,  
  20.     JOB_GROUP VARCHAR2(200) NOT NULL,  
  21.     DESCRIPTION VARCHAR2(250) NULL,  
  22.     JOB_CLASS_NAME   VARCHAR2(250) NOT NULL,   
  23.     IS_DURABLE VARCHAR2(1) NOT NULL,  
  24.     IS_NONCONCURRENT VARCHAR2(1) NOT NULL,  
  25.     IS_UPDATE_DATA VARCHAR2(1) NOT NULL,  
  26.     REQUESTS_RECOVERY VARCHAR2(1) NOT NULL,  
  27.     JOB_DATA BLOB NULL,  
  28.     CONSTRAINT QRTZ_JOB_DETAILS_PK PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)  
  29. );  
  30. CREATE TABLE qrtz_triggers  
  31.   (  
  32.     SCHED_NAME VARCHAR2(120) NOT NULL,  
  33.     TRIGGER_NAME VARCHAR2(200) NOT NULL,  
  34.     TRIGGER_GROUP VARCHAR2(200) NOT NULL,  
  35.     JOB_NAME  VARCHAR2(200) NOT NULL,   
  36.     JOB_GROUP VARCHAR2(200) NOT NULL,  
  37.     DESCRIPTION VARCHAR2(250) NULL,  
  38.     NEXT_FIRE_TIME NUMBER(13) NULL,  
  39.     PREV_FIRE_TIME NUMBER(13) NULL,  
  40.     PRIORITY NUMBER(13) NULL,  
  41.     TRIGGER_STATE VARCHAR2(16) NOT NULL,  
  42.     TRIGGER_TYPE VARCHAR2(8) NOT NULL,  
  43.     START_TIME NUMBER(13) NOT NULL,  
  44.     END_TIME NUMBER(13) NULL,  
  45.     CALENDAR_NAME VARCHAR2(200) NULL,  
  46.     MISFIRE_INSTR NUMBER(2) NULL,  
  47.     JOB_DATA BLOB NULL,  
  48.     CONSTRAINT QRTZ_TRIGGERS_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),  
  49.     CONSTRAINT QRTZ_TRIGGER_TO_JOBS_FK FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)   
  50.       REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)   
  51. );  
  52. CREATE TABLE qrtz_simple_triggers  
  53.   (  
  54.     SCHED_NAME VARCHAR2(120) NOT NULL,  
  55.     TRIGGER_NAME VARCHAR2(200) NOT NULL,  
  56.     TRIGGER_GROUP VARCHAR2(200) NOT NULL,  
  57.     REPEAT_COUNT NUMBER(7) NOT NULL,  
  58.     REPEAT_INTERVAL NUMBER(12) NOT NULL,  
  59.     TIMES_TRIGGERED NUMBER(10) NOT NULL,  
  60.     CONSTRAINT QRTZ_SIMPLE_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),  
  61.     CONSTRAINT QRTZ_SIMPLE_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)   
  62. REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)  
  63. );  
  64. CREATE TABLE qrtz_cron_triggers  
  65.   (  
  66.     SCHED_NAME VARCHAR2(120) NOT NULL,  
  67.     TRIGGER_NAME VARCHAR2(200) NOT NULL,  
  68.     TRIGGER_GROUP VARCHAR2(200) NOT NULL,  
  69.     CRON_EXPRESSION VARCHAR2(120) NOT NULL,  
  70.     TIME_ZONE_ID VARCHAR2(80),  
  71.     CONSTRAINT QRTZ_CRON_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),  
  72.     CONSTRAINT QRTZ_CRON_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)   
  73.       REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)  
  74. );  
  75. CREATE TABLE qrtz_simprop_triggers  
  76.   (            
  77.     SCHED_NAME VARCHAR2(120) NOT NULL,  
  78.     TRIGGER_NAME VARCHAR2(200) NOT NULL,  
  79.     TRIGGER_GROUP VARCHAR2(200) NOT NULL,  
  80.     STR_PROP_1 VARCHAR2(512) NULL,  
  81.     STR_PROP_2 VARCHAR2(512) NULL,  
  82.     STR_PROP_3 VARCHAR2(512) NULL,  
  83.     INT_PROP_1 NUMBER(10) NULL,  
  84.     INT_PROP_2 NUMBER(10) NULL,  
  85.     LONG_PROP_1 NUMBER(13) NULL,  
  86.     LONG_PROP_2 NUMBER(13) NULL,  
  87.     DEC_PROP_1 NUMERIC(13,4) NULL,  
  88.     DEC_PROP_2 NUMERIC(13,4) NULL,  
  89.     BOOL_PROP_1 VARCHAR2(1) NULL,  
  90.     BOOL_PROP_2 VARCHAR2(1) NULL,  
  91.     CONSTRAINT QRTZ_SIMPROP_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),  
  92.     CONSTRAINT QRTZ_SIMPROP_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)   
  93.       REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)  
  94. );  
  95. CREATE TABLE qrtz_blob_triggers  
  96.   (  
  97.     SCHED_NAME VARCHAR2(120) NOT NULL,  
  98.     TRIGGER_NAME VARCHAR2(200) NOT NULL,  
  99.     TRIGGER_GROUP VARCHAR2(200) NOT NULL,  
  100.     BLOB_DATA BLOB NULL,  
  101.     CONSTRAINT QRTZ_BLOB_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),  
  102.     CONSTRAINT QRTZ_BLOB_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)   
  103.         REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)  
  104. );  
  105. CREATE TABLE qrtz_calendars  
  106.   (  
  107.     SCHED_NAME VARCHAR2(120) NOT NULL,  
  108.     CALENDAR_NAME  VARCHAR2(200) NOT NULL,   
  109.     CALENDAR BLOB NOT NULL,  
  110.     CONSTRAINT QRTZ_CALENDARS_PK PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)  
  111. );  
  112. CREATE TABLE qrtz_paused_trigger_grps  
  113.   (  
  114.     SCHED_NAME VARCHAR2(120) NOT NULL,  
  115.     TRIGGER_GROUP  VARCHAR2(200) NOT NULL,   
  116.     CONSTRAINT QRTZ_PAUSED_TRIG_GRPS_PK PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)  
  117. );  
  118. CREATE TABLE qrtz_fired_triggers   
  119.   (  
  120.     SCHED_NAME VARCHAR2(120) NOT NULL,  
  121.     ENTRY_ID VARCHAR2(95) NOT NULL,  
  122.     TRIGGER_NAME VARCHAR2(200) NOT NULL,  
  123.     TRIGGER_GROUP VARCHAR2(200) NOT NULL,  
  124.     INSTANCE_NAME VARCHAR2(200) NOT NULL,  
  125.     FIRED_TIME NUMBER(13) NOT NULL,  
  126.     SCHED_TIME NUMBER(13) NOT NULL,  
  127.     PRIORITY NUMBER(13) NOT NULL,  
  128.     STATE VARCHAR2(16) NOT NULL,  
  129.     JOB_NAME VARCHAR2(200) NULL,  
  130.     JOB_GROUP VARCHAR2(200) NULL,  
  131.     IS_NONCONCURRENT VARCHAR2(1) NULL,  
  132.     REQUESTS_RECOVERY VARCHAR2(1) NULL,  
  133.     CONSTRAINT QRTZ_FIRED_TRIGGER_PK PRIMARY KEY (SCHED_NAME,ENTRY_ID)  
  134. );  
  135. CREATE TABLE qrtz_scheduler_state   
  136.   (  
  137.     SCHED_NAME VARCHAR2(120) NOT NULL,  
  138.     INSTANCE_NAME VARCHAR2(200) NOT NULL,  
  139.     LAST_CHECKIN_TIME NUMBER(13) NOT NULL,  
  140.     CHECKIN_INTERVAL NUMBER(13) NOT NULL,  
  141.     CONSTRAINT QRTZ_SCHEDULER_STATE_PK PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)  
  142. );  
  143. CREATE TABLE qrtz_locks  
  144.   (  
  145.     SCHED_NAME VARCHAR2(120) NOT NULL,  
  146.     LOCK_NAME  VARCHAR2(40) NOT NULL,   
  147.     CONSTRAINT QRTZ_LOCKS_PK PRIMARY KEY (SCHED_NAME,LOCK_NAME)  
  148. );  
  149.    
  150. create index idx_qrtz_j_req_recovery on qrtz_job_details(SCHED_NAME,REQUESTS_RECOVERY);  
  151. create index idx_qrtz_j_grp on qrtz_job_details(SCHED_NAME,JOB_GROUP);  
  152.    
  153. create index idx_qrtz_t_j on qrtz_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP);  
  154. create index idx_qrtz_t_jg on qrtz_triggers(SCHED_NAME,JOB_GROUP);  
  155. create index idx_qrtz_t_c on qrtz_triggers(SCHED_NAME,CALENDAR_NAME);  
  156. create index idx_qrtz_t_g on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP);  
  157. create index idx_qrtz_t_state on qrtz_triggers(SCHED_NAME,TRIGGER_STATE);  
  158. create index idx_qrtz_t_n_state on qrtz_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);  
  159. create index idx_qrtz_t_n_g_state on qrtz_triggers(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);  
  160. create index idx_qrtz_t_next_fire_time on qrtz_triggers(SCHED_NAME,NEXT_FIRE_TIME);  
  161. create index idx_qrtz_t_nft_st on qrtz_triggers(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);  
  162. create index idx_qrtz_t_nft_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);  
  163. create index idx_qrtz_t_nft_st_misfire on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);  
  164. create index idx_qrtz_t_nft_st_misfire_grp on qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);  
  165.    
  166. create index idx_qrtz_ft_trig_inst_name on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME);  
  167. create index idx_qrtz_ft_inst_job_req_rcvry on qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);  
  168. create index idx_qrtz_ft_j_g on qrtz_fired_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP);  
  169. create index idx_qrtz_ft_jg on qrtz_fired_triggers(SCHED_NAME,JOB_GROUP);  
  170. create index idx_qrtz_ft_t_g on qrtz_fired_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);  
  171. create index idx_qrtz_ft_tg on qrtz_fired_triggers(SCHED_NAME,TRIGGER_GROUP);  

 

 

我在新建一个张表,为了方便页面能对每个任务进行管理,能对具体某个任务设置开始时间、结束时间、执行的方法、删除等, 如下面图所示:

 

 

 

在这边可以管理开始时间和结束时间和cronExpression值,方便管理对应表的设计:

 

 

 

表都设计好了,整理Quartz集成springMVC的具体的实现。

spring@component 的说明:@component (把普通pojo实例化到spring容器中,相当于配置文件中的<bean id="" class=""/>

 

1.举例个任务具体实现功能,列如quartzJobA和quartzJobB任务要做什么,新建了两个类和方法。

  

[java] view plain copy
 
  1. import org.springframework.stereotype.Component;  
  2.   
  3. @Component("quartzJobA")  
  4. public class Data2ServiceImpl {  
  5.   
  6.     public void run() {  
  7.         System.out.println("=============Data2ServiceImpl=========");  
  8.           
  9.     }  
  10. }  
  11.   
  12. @Component("quartzJobB")  
  13. public class DataServiceImpl {  
  14.   
  15.     
  16.     public void test() {  
  17.         System.out.println("=============DataServiceImpl=========");  
  18.           
  19.     }  
  20.   
  21. }  

 

 

 

2.Quartz 调度任务所需的配置文件 quartz-job.properties

  

 

[java] view plain copy
 
  1. #Main Scheduler Settings  
  2. org.quartz.scheduler.instanceName=quartzScheduler    
  3. org.quartz.scheduler.instanceId=AUTO  
  4. org.quartz.scheduler.threadsInheritContextClassLoaderOfInitializer=true  
  5. org.quartz.scheduler.skipUpdateCheck=true  
  6. org.quartz.scheduler.batchTriggerAcquisitionMaxCount=100  
  7.   
  8. org.quartz.threadPool.threadCount=10  
  9.   
  10. #Configure JDBC-JobStoreTX  
  11. org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX  
  12. org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.oracle.OracleDelegate  
  13. org.quartz.jobStore.dataSource=myDS  
  14. org.quartz.jobStore.tablePrefix=QRTZ_  
  15. org.quartz.jobStore.isClustered=true  
  16. org.quartz.jobStore.acquireTriggersWithinLock=true  
  17. org.quartz.jobStore.clusterCheckinInterval = 30000  
  18.   
  19. #Configure DataSources  
  20. org.quartz.dataSource.myDS.driver=com.alibaba.druid.proxy.DruidDriver  
  21. org.quartz.dataSource.myDS.URL=jdbc:wrap-jdbc:filters=default:name=dragoon:jdbc:oracle:thin:@127.0.0.1:1521:test  
  22. org.quartz.dataSource.myDS.user=  
  23. org.quartz.dataSource.myDS.password=  
  24. org.quartz.dataSource.myDS.maxConnections=5  
  25. org.quartz.dataSource.myDS.validationQuery=select 1 from dual  

org.quartz.scheduler.instanceName 属性可为任何值,用在 JDBC JobStore 中来唯一标识实例,但是所有集群节点中必须相同 

org.quartz.jobStore.class属性为 JobStoreTX,将任务持久化到数据中。因为集群中节点依赖于数据库来传播 Scheduler 实例的状态,你只能在使用 JDBC JobStore 时应用 Quartz 集群。这意味着你必须使用 JobStoreTX 或是 JobStoreCMT 作为 Job 存储;你不能在集群中使用 RAMJobStore

3.实现任务的创建和管理

   

[java] view plain copy
 
  1. @Component("schedulerHelper")  
  2. public class SchedulerHelper  
  3. {  
  4.   
  5.     private static final String CONFIG_FILE="quartz-job.properties";  
  6.     private static final String IDENTITY_JOB_PREFIX="job_";  
  7.     private static final String IDENTITY_TRIGGER_PREFIX="trigger_";  
  8.           
  9.        @Autowired  
  10.     private JobService jobService;//jobService 这个服务是实现管理任务的页面的服务实现  
  11.     private Scheduler scheduler;  
  12.       
  13.       
  14.   
  15.     @Autowired  
  16.     private StartJobSchedulerListener startJobSchedulerListener;//实现自己的Scheduler监听器,程序启动时,任务没创建时就创建  
  17.   
  18.       
  19.       
  20.       
  21.        /** 
  22.      * tomcat一启动时,类实例化时就执行 
  23.      */  
  24.     public void  init()  
  25.     {  
  26.         try{  
  27.                
  28.              // 创建一个定时器工厂  
  29.             StdSchedulerFactory sf = new StdSchedulerFactory();  
  30.                         //初始化quartz-job.properties配置文件  
  31.             sf.initialize(Thread.currentThread().getContextClassLoader().getResource(CONFIG_FILE).getFile());  
  32.             scheduler = sf.getScheduler();  
  33.             //把jobService放到scheduler上下文,job执行是可以获取并访问。  
  34.             scheduler.getContext().put(SCHEDULER_KEY_JOBSERVICE,jobService);  
  35.             startJobSchedulerListener.setSchedulerHelper(this);  
  36.                          //设置自己的监听器  
  37.             scheduler.getListenerManager().addSchedulerListener(startJobSchedulerListener);  
  38.                        // 启动定时器  
  39.             scheduler.start();  
  40.             logger.info("====================job scheduler start");           
  41.         }catch(SchedulerException e){  
  42.             logger.error("error",e);              
  43.         }  
  44.           
  45.     }  
  46.       
  47.           
  48.          /** 
  49.      * 根据jobentity创建并开始任务 
  50.      */  
  51.    public boolean createAndStartJob(JobEntity job)  
  52.     {  
  53.         JobDetail jobDetail=generateJobDetail(job);  
  54.         Trigger trigger=generateTriggerBuilder(job).build();  
  55.           
  56.         try {  
  57.             scheduler.scheduleJob(jobDetail, trigger);  
  58.             return true;  
  59.         } catch (SchedulerException e) {  
  60.             logger.error("scheduler.scheduleJob",e);  
  61.             return false;  
  62.         }  
  63.     }  
  64.         /** 
  65.      * 清除 
  66.      */  
  67.     public void clearAllScheduler()  
  68.     {  
  69.         try {  
  70.             scheduler.clear();  
  71.         } catch (SchedulerException e) {  
  72.             logger.error("clearAllScheduler",e);  
  73.         }  
  74.     }  
  75.       
  76.           
  77.          /** 
  78.      * 根据jobId和类型删除 
  79.      */  
  80.     public boolean removeJob(Long jobId,String jobType)   
  81.     {  
  82.         try {  
  83.             scheduler.deleteJob(getJobKey(jobId,jobType));  
  84.             return true;  
  85.         } catch (SchedulerException e) {  
  86.             logger.error("removeJob",e);  
  87.             return false;  
  88.         }         
  89.     }  
  90.           
  91.          /** 
  92.      * 暂停任务 
  93.      */  
  94.     public boolean pauseJob(Long jobId,String jobType)  
  95.     {  
  96.         try {  
  97.             scheduler.pauseJob(getJobKey(jobId,jobType));  
  98.             return true;  
  99.         } catch (SchedulerException e) {  
  100.             logger.error("resumeJob",e);  
  101.             return false;  
  102.         }  
  103.     }  
  104.        
  105.         /** 
  106.      * 马上只执行一次任务 
  107.      */  
  108.     public boolean executeOneceJob(Long jobId,String jobType)  
  109.     {  
  110.         try {  
  111.             Calendar end=Calendar.getInstance();              
  112.             TriggerBuilder<SimpleTrigger> simpleTriggerBuilder=TriggerBuilder.newTrigger()  
  113.                                                 .withIdentity(getTriggerKey(jobId,jobType))  
  114.                                                 .forJob(getJobKey(jobId,jobType))  
  115.                                                 .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(2));  
  116.             end.add(Calendar.SECOND, 2);  
  117.             simpleTriggerBuilder.startAt(end.getTime());  
  118.             end.add(Calendar.SECOND, 5);  
  119.             simpleTriggerBuilder.endAt(end.getTime());  
  120.             JobEntity job=jobService.getJobById(jobId);  
  121.               
  122.             JobDataMap jobDataMap=new JobDataMap();  
  123.             jobDataMap.put("jobEntity", job);  
  124.             simpleTriggerBuilder.usingJobData(jobDataMap);  
  125.             Trigger trigger=simpleTriggerBuilder.build();  
  126.               
  127.             scheduler.scheduleJob(trigger);  
  128.             return true;  
  129.         } catch (SchedulerException e) {  
  130.             logger.error("executeOneceJob",e);  
  131.             return false;  
  132.         }  
  133.     }  
  134.         /** 
  135.      * 启动一些scheduler里没有的active的jobDetail 
  136.      */  
  137.     public void createActiveJobFromDB() throws SchedulerException  
  138.     {  
  139.         List<JobEntity> jobs=jobService.getActiveJob();  
  140.         for(JobEntity job:jobs)  
  141.         {  
  142.             if(scheduler.getJobDetail(getJobKey(job))==null)  
  143.                 createAndStartJob(job);  
  144.         }  
  145.     }  
  146.           
  147.        /** 
  148.      * 获得任务的jobKey 
  149.      */  
  150.     public static JobKey getJobKey(Long jobId,String jobType)  
  151.     {  
  152.         return new JobKey(IDENTITY_JOB_PREFIX+jobId,IDENTITY_JOB_PREFIX+jobType);  
  153.     }  
  154.       
  155.       /** 
  156.      * 获得任务的jobKey 
  157.      */  
  158.   
  159.     public static JobKey getJobKey(JobEntity job)  
  160.     {  
  161.         return new JobKey(IDENTITY_JOB_PREFIX+job.getJobId(),IDENTITY_JOB_PREFIX+job.getJobType());  
  162.     }  
  163.       
  164.     /** 
  165.      * 获得trigger的triggerkey 
  166.      */  
  167.     public static TriggerKey getTriggerKey(JobEntity job)  
  168.     {  
  169.         return new TriggerKey(IDENTITY_TRIGGER_PREFIX+job.getJobId()+"_"+System.currentTimeMillis(), IDENTITY_TRIGGER_PREFIX+job.getJobType());  
  170.     }  
  171.       
  172.   
  173.         /** 
  174.      * 获得trigger的triggerkey 
  175.      */  
  176.     public static TriggerKey getTriggerKey(Long jobId,String jobType)  
  177.     {  
  178.         return new TriggerKey(IDENTITY_TRIGGER_PREFIX+jobId+"_"+System.currentTimeMillis(), IDENTITY_TRIGGER_PREFIX+jobType);  
  179.     }  
  180.       
  181.     public static JobDetail generateJobDetail(JobEntity job)  
  182.     {  
  183.         JobDataMap jobDataMap=new JobDataMap();  
  184.         jobDataMap.put("jobEntity", job);  
  185.         Class<? extends Job> clazz=null;  
  186.          clazz=BeanJob.class;  
  187.         return JobBuilder.newJob(clazz)  
  188.                         .withIdentity(getJobKey(job))  
  189.                         .usingJobData(jobDataMap)  
  190.                         .requestRecovery(true).storeDurably(true)  
  191.                         .build();  
  192.     }  
  193.       
  194.       
  195.        /** 
  196.      * 根据jobEntity获得trigger 
  197.      */  
  198.   
  199.     public static TriggerBuilder<CronTrigger> generateTriggerBuilder(JobEntity job)  
  200.     {  
  201.         TriggerBuilder<CronTrigger> triggerBuilder= TriggerBuilder.newTrigger()  
  202.                 .withIdentity(getTriggerKey(job))  
  203.                 .withSchedule(CronScheduleBuilder.cronSchedule(job.getCronExpr())  
  204.                                                 .withMisfireHandlingInstructionDoNothing());  
  205.         if(job.getSyncBeginTime()!=null)  
  206.             triggerBuilder.startAt(job.getSyncBeginTime());  
  207.         else  
  208.             triggerBuilder.startNow();  
  209.           
  210.         if(job.getSyncEndTime()!=null)  
  211.             triggerBuilder.endAt(job.getSyncEndTime());  
  212.       
  213.         return triggerBuilder;  
  214.     }  
  215.       
  216.     public static JobService getJobService(JobExecutionContext context)  
  217.     {  
  218.         try {  
  219.             return (JobService) context.getScheduler().getContext().get(SchedulerHelper.SCHEDULER_KEY_JOBSERVICE);  
  220.         } catch (SchedulerException e) {  
  221.             logger.error("SchedulerHelper.getJobService",e);  
  222.             return null;  
  223.         }  
  224.     }  
  225.       

 

 

 

 

4.实现自己的Scheduler监听器,程序启动时,创建scheduler里没有的activejobDetail

   

[java] view plain copy
 
  1. @Component(value="startJobSchedulerListener")  
  2. public class StartJobSchedulerListener extends SchedulerListenerSupport   
  3. {  
  4.     private SchedulerHelper schedulerHelper;  
  5.       
  6.     @Override  
  7.     public void schedulerStarted()  
  8.     {  
  9.         try {  
  10.             schedulerHelper.createActiveJobFromDB();  
  11.         } catch (SchedulerException e) {  
  12.             logger.error("createActiveJobFromDB",e);  
  13.         }  
  14.     }  
  15.   
  16.     public SchedulerHelper getSchedulerHelper() {  
  17.         return schedulerHelper;  
  18.     }  
  19.   
  20.     public void setSchedulerHelper(SchedulerHelper schedulerHelper) {  
  21.         this.schedulerHelper = schedulerHelper;  
  22.     }  
  23.   
  24.               
  25. }  

5.实现的是一个job实例对应一个线程并实现页面配置对应的哪个类和方法

 

  

[java] view plain copy
 
  1. public abstract class AbstractEdiJob implements Job   
  2. {  
  3.     protected JobEntity jobEntity;   
  4.     protected static final Logger logger=LoggerFactory.getLogger(AbstractEdiJob.class);  
  5.     private Long beginTime;  
  6.           
  7.     @Override  
  8.     public void execute(JobExecutionContext context) throws JobExecutionException   
  9.     {  
  10.         JobService jobService=SchedulerHelper.getJobService(context);  
  11.         preExcute(jobService,context);  
  12.         exeucuteInternal(context);  
  13.         postExcute(jobService,context);  
  14.     }  
  15.       
  16.     abstract public void exeucuteInternal(JobExecutionContext context);  
  17.       
  18.     public void preExcute(JobService jobService,JobExecutionContext context)  
  19.     {  
  20.         beginTime=System.currentTimeMillis();  
  21.     }  
  22.       
  23.     public void postExcute(JobService jobService,JobExecutionContext context)  
  24.     {  
  25.         //获得最新的jobEntiry  
  26.         jobEntity=jobService.getJobById(jobEntity.getJobId());  
  27.         if(jobEntity==null)  
  28.         {  
  29.             logger.warn(jobEntity.getJobId()+"job不能存在");  
  30.             return;  
  31.         }  
  32.         if(context.getFireTime()!=null)  
  33.             jobEntity.setRuntimeLast(context.getFireTime());  
  34.         if(context.getNextFireTime()!=null)  
  35.             jobEntity.setRuntimeNext(context.getNextFireTime());  
  36.     /*  else 
  37.             jobEntity.setJobStatus();*/  
  38.         Long times=jobEntity.getRunTimes();  
  39.         jobEntity.setRunTimes((times==null?0l:times)+1);  
  40.         Long duration=jobEntity.getRunDuration();  
  41.         jobEntity.setRunDuration((duration==null?0l:duration)+(System.currentTimeMillis()-beginTime));  
  42.         jobService.updateJob(jobEntity);  
  43.         //jobEntity这里的改变不能改变JobDetail里的JobEntity,因为生产的job是JobDetail的JobEntity的复制  
  44.     }  
  45.   
  46.   
  47.     public void setJobEntity(JobEntity jobEntity) {  
  48.         this.jobEntity = jobEntity;  
  49.     }  
  50.   
  51.   
  52. }  

 

[java] view plain copy
 
  1. /** 
  2.  *执行具体类中的方法 
  3.  **/  
  4. public class BeanJob extends AbstractEdiJob   
  5. {  
  6.     private static Logger logger=LoggerFactory.getLogger(BeanJob.class);  
  7.     @Override  
  8.     public void exeucuteInternal(JobExecutionContext context)   
  9.     {  
  10.         Object obj=SpringContextUtil.getBean(jobEntity.getJobObject());  
  11.         try {  
  12.             Method method=obj.getClass().getMethod(jobEntity.getJobMethod());  
  13.             method.invoke(obj);  
  14.         } catch (SecurityException e) {  
  15.             logger.error("error",e);  
  16.         } catch (NoSuchMethodException e) {  
  17.             logger.error("error",e);  
  18.         } catch (IllegalArgumentException e) {  
  19.             logger.error("error",e);  
  20.         } catch (IllegalAccessException e) {  
  21.             logger.error("error",e);  
  22.         } catch (InvocationTargetException e) {  
  23.             logger.error("error",e);  
  24.         }  
  25.     }  
  26.   
  27. }  



 

6.新增一个任务时,数据库就保存对应的触发器,变成持久化任务,如图所示:

  


    1.用StdSchedulerFactory来获取Scheduler的实例,scheduler有启动(start)、中止(stop)和暂停(pause)方法。
    2.JobDataMap实例,JobDataMap jobDataMap=new JobDataMap();jobDataMap.put("jobEntity", job);在同一任务的多次执行之间传递数据
    3.创建JobDetail实例。JobBuilder.newJob(clazz).withIdentity(getJobKey(job)).usingJobData(jobDataMap).requestRecovery(true).storeDurably(true).build();返回JobDetail实例,newJob(clazz)是要执行特定任务的类;withIdentity(getJobKey(job))是job的任务名和组名;usingJobDatausingJobData(jobDataMap)传输数据;


    4.创建Trigger实例。TriggerBuilder<CronTrigger> triggerBuilder= TriggerBuilder.newTrigger()
                                                                                                .withIdentity(getTriggerKey(job))
                                                                                     .withSchedule(CronScheduleBuilder.cronSchedule(job.getCronExpr())
                      .withMisfireHandlingInstructionDoNothing());

   withIdentity有标示了触发器的名称和组(Quartz调度是通过触发器的类别来识别不同的任务),和withSchedule标示执行的时间表达式

 


    5.最后通过scheduler.scheduleJob()方法调度任务

分享到:
评论
1 楼 明兜3号 2018-10-08  
基于spring+quartz的分布式任务调度
网盘地址:https://pan.baidu.com/s/1mhcz0iUwHo6SeniLakYu-w 提取码: fneg
备用地址(腾讯微云):https://share.weiyun.com/5lxBBCJ 密码:bc8efs

相关推荐

    springMVC+Mybatis+quartz+log4j+maven项目

    在分布式环境中,Quartz可以实现集群,确保高可用性和任务的可靠性。 4. **Log4j**:Log4j是Apache的一个开源日志框架,用于记录应用程序运行过程中的各种信息。通过配置,可以选择不同的日志级别(如DEBUG、INFO、...

    ssm分布式任务调度系统.rar

    SSM分布式任务调度系统是基于Spring、SpringMVC和MyBatis这三大主流Java开发框架构建的高效能、可扩展的任务调度平台。该系统旨在解决大规模集群环境下的任务分配、执行与监控问题,广泛应用于大数据处理、定时任务...

    springMvc定时器执行两次

    3. **多实例运行**:在分布式环境下,如果未正确配置Job的持久化和集群设置,每个节点都可能独立调度任务。 4. **Spring的初始化回调**:有时Spring的初始化回调机制会导致Job被触发两次,需要确保回调方法中对Job...

    SpringMVC+Nutz框架介绍范本模板.docx

    \n\n权限体系方面,基于Shiro的深度改造,不仅使用Ehcache提升一级缓存性能,还利用Redis实现二级缓存的持久化和session同步。通过Shiro注解,实现了按钮级、方法级的权限控制,构建了平台、商家和会员三套独立的...

    iBase4j快速开发框架

    iBase4J是一个基于SpringBoot 2.0、SpringMVC和Mybatis的快速开发框架,它集成了mybatis-plus、motan/dubbo分布式服务、Redis缓存、Shiro权限管理以及Quartz分布式集群调度等多种功能。这个框架设计用于构建分布式...

    java简历模版5.doc

    - **消息队列**:熟练使用RabbitMQ处理异步任务和流量控制,以及Mycat数据库中间件。 - **数据库**:熟悉MySQL的DDL、DML和事务管理,具备优化能力。 - **全文搜索**:掌握Solr和Elasticsearch,能进行大规模数据...

    前后端分离的Java快速开发平台之轻量级权限管理系统

    通过Quartz分布式集群调度,可以实现定时任务的高效、稳定执行。Quartz是一个开源的作业调度框架,可以用于安排和执行周期性的任务。 部门管理功能是企业级系统中不可或缺的部分,它允许组织按照实际的组织架构进行...

    Eclipse开发分布式商城系统+完整视频代码及文档

    ├─补充1:拔高课程(Redis3.0持久化、集群、MySQL5.6优化、Tomcat7优化) │ │ 打开必读.txt │ │ │ ├─课前资料 │ │ ├─MySQL5.6优化 │ │ │ MySql5.6性能优化.docx │ │ │ │ │ ├─Redis集群 │ ...

    XXX-JAVA开发工程师-2年经验简历模板

    - **Eureka/Zuul/Hystrix/Feign/Ribbon/Quartz/Dashboard/Turbine**:这些都是Spring Cloud生态系统中的组件或服务,分别用于服务发现、API网关、容错处理、服务调用、负载均衡、定时任务调度、监控和服务聚合等功能...

    淘淘商城项目

    - **定时器**:Quartz,实现定时任务调度。 - **Web服务器**:Tomcat,承载应用服务。 - **工程管理**:Maven,实现项目的自动化构建和依赖管理。 #### 五、开发工具与环境 - **集成开发环境**:Eclipse 4.5.0 ...

    收集java学习资料和面试题包括git上好的项目

    - 分布式任务调度 - 失败重试机制 ##### 15. Redis - **简介**:一个开源的键值存储系统。 - **链接**:[https://redis.io/](https://redis.io/) - **核心特性**: - 内存数据结构存储 - 数据持久化 - 发布...

    面试宝典-v4.0

    - Redis(缓存数据库):可能讲解了Redis的基础知识、数据类型、持久化机制、集群配置及与Java的交互方式。 - Quartz:可能介绍了定时任务调度器Quartz的基本使用和监控Job执行状态的方法。 - MQ(消息队列):可能...

    java高级工程师面试总结

    - Redis提供了持久化机制,而Memcached只存在于内存中。 - Redis支持事务,可以进行批量操作。 - **如何实现Redis的分片**: - 使用客户端分片,如Jedis Cluster。 - 服务器端实现,如使用Hash slots进行数据分...

    Java工程师面试宝典

    - **持久化机制**:保证消息的持久化存储。 - **ActiveMQ**: - **作用与原理**:基于JMS标准的消息中间件。 - **应用场景**:异步处理、消息解耦。 - **数据提交不成功处理**:重试机制或回滚操作。 #### 电商...

Global site tag (gtag.js) - Google Analytics