Quartz 任務調度機制筆記——01

實例:html

一、代碼實現Demomysql

@Test sql

    public void demo01() throws InterruptedException{數據庫

       //獲取調度器網站

       SchedulerFactory schedulerFactory = new StdSchedulerFactory();ui

       Scheduler scheduler = null;spa

       try {.net

           scheduler = StdSchedulerFactory.getDefaultScheduler();線程

          

           //引進做業程序這,裏的HelloJob是一個Job的繼承類,重載的excute方法xml

           JobDetail jobDetail = JobBuilder.newJob(HelloJob.class)

                                           .withIdentity("helloJob", "group01" )

                                           .build();

           //生成一個觸發器,這裏這個SimpleTriggerImpl能夠被其餘的Trigger替換掉的

           SimpleTriggerImpl simpleTriggerImpl = new SimpleTriggerImpl( "trigger", "group01" );

          //我使用的是:

           //Trigger simpleTriggerImpl = TriggerBuilder.newTrigger().withIdentity("trigger", "group01").build();

           simpleTriggerImpl.setStartTime( new Date(System.currentTimeMillis()));

          

           simpleTriggerImpl.setRepeatInterval(2000);

           simpleTriggerImpl.setRepeatCount(10);

          

           //做業和觸發器設置到調度器中

           scheduler.scheduleJob(jobDetail, simpleTriggerImpl);

           //啓動調度器

           System. out.println(jobDetail.getKey().toString());

           scheduler.start();

   //注意,在Quartz中,這個調度器的生命週期是和主線程相關的,全部若是主線程退出了,那麼調度器也就結束了

           Thread. sleep(20000);

        } catch (SchedulerException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }finally{

            System. out.println(HelloJob. count);

        }

    }


二、配置文件實現:Demo

quartz.properties


org.quartz.scheduler.instanceName = TestScheduler

org.quartz.scheduler.instanceId = one


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

org.quartz.threadPool.threadCount =  2

org.quartz.threadPool.threadPriority = 4


org.quartz.plugin.jobInitializer.class = org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin

org.quartz.plugin.jobInitializer.fileNames = jobs.xml #本身的job配置文件

org.quartz.plugin.jobInitializer.failOnFileNotFound = true

org.quartz.plugin.jobInitializer.scanInterval = 10

org.quartz.plugin.jobInitializer.wrapInUserTransaction = false


jobs.xml


<?xml version='1.0' encoding= 'utf-8'?>

<job-scheduling-data xmlns= "http://www.quartz-scheduler.org/xml/JobSchedulingData"

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

  xsi:schemaLocation="http://www.quartz-scheduler.org/xml/JobSchedulingData

                          http://www.quartz-scheduler.org/xml/job_scheduling_data_1_8.xsd" version= "1.8">

  < schedule>

  < job>         

    <name >hello </name >

    <group >MYJOB_GROUP </group >

    <description >The job description </description >

    <job-class >com.qunar.xueping.HelloJob </job-class > ##這是爲本身的job實現類

    <job-data-map > #設置JobDataMap key-value

      <entry >

          <key >key </key >

          <value >hotdog</value>

       </entry >

       <entry >

           <key >key2 </key >

           <value >ketchup, mayo</ value>

       </entry >

     </job-data-map >  

   </job >

     

    <trigger >     

     <simple >     

       <name >scanTrigger </name >     

       <group >DEFAULT </group >     

       <job-name >hello </job-name >     

       <job-group >MYJOB_GROUP </job-group >           

       <repeat-count >3 </repeat-count >     

       <repeat-interval >1000 </repeat-interval >     

     </simple >     

    </trigger >        

  </ schedule>

</job-scheduling-data>

注:具體的Schedule調度: 

scheduler = StdSchedulerFactory.getDefaultScheduler(); 

schedule.start();


進階:


一、在調度器中表示一個job或者一個trigger的方式是經過一個JobKey來表示的,

JobKey jobKey = new JobKey("name" , "group");

Scheduler能夠對job和Trigger進行一些操做


二、在進行任務調度過程當中,能夠經過JobDataMap來put Info到Job中去


三、經過SchedulerMetaData metaData = schedule.getMetaData(),裏面有一些schedule的常見設置,例如threadPool的size,另外值得注意的是,metaData.getNumberOfJobsException()方法,這個方法返回的是當先執行了多少個job

(疑問:爲何個人Trigger的withRepeatCount設置的是10,但最終job的excute方法執行了11次)


四、注意Job的兩個註釋:@PersistJobDataAfterExecution @DisallowConcurrentExecution 作什麼用,顧名思義啦


五、關於故障的恢復:

     在Quartz中對於故障的解決辦法是將job persist到數據中,而後經過狀態標識Recovering須要恢復的Job

          參考網站:http://ygydaiaq-gmail-com.iteye.com/blog/1729626

                                http://www.24xuexi.com/w/2011-04-16/88179.html

六、Listener:quartz有本身的監聽器JobListener,TriggerListstener,SchedulerListerner

舉例:JobListener:

public class MyJobListener implements JobListener{


    public String getName() {

        // TODO Auto-generated method stub

        return "MyJobListener";

    }

    public void jobToBeExecuted(JobExecutionContext context) {

        // TODO Auto-generated method stub

        System.out.println(context.getJobDetail().getJobDataMap().getString("key")+"jobToBeExecuted----");

    }


    public void jobExecutionVetoed(JobExecutionContext context) {

        // TODO Auto-generated method stub

        System.out.println(context.getJobDetail().getJobDataMap().getString("key")+"jobExecutionVetoed----");

    }


    public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {

        // TODO Auto-generated method stub

        System.out.println(context.getJobDetail().getJobDataMap().getString("key")+"jobWasExecuted----");

    }


}


設置Listener:

 @Test

    public void testJob03(){

        Scheduler scheduler  = null;

        try {

            scheduler = StdSchedulerFactory.getDefaultScheduler();

            scheduler.getListenerManager()

     .addJobListener(new MyJobListener() , KeyMatcher.keyEqualsnew JobKey("hello" , "MYJOB_GROUP")));

            scheduler.start();

            Thread. sleep(20000);

        } catch (Exception e) {

            // TODO: handle exception

            e.printStackTrace();

        }

    }

七、Quartz的故障恢復機制

默認狀況下,Quartz中所提交的任務都是獨立的運行在線程中,這意味着機器出現故障或任何緣由致使這個線程被幹掉了,那麼提交的任務就沒法繼續也沒法恢復

解決方法:在出現故障時將任務進行的狀態保存下來,Quartz內置了數據庫持久化的模塊

配置文件:quartz.xml

#配置RAMJobStore

org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore


#數據庫配置

org.quartz.jobStore.misfireThreshold=60000

org.quartz.jobStore.class=org.quartz.simpl.RAMJobStore


org.quartz.dataSource.DATA_SOURCE_NAME.driver=com.mysql.jdbc.Driver

org.quartz.dataSource.DATA_SOURCE_NAME.URL=jdbc:mysql://localhost:3306/ dbname

org.quartz.dataSource.DATA_SOURCE_NAME.user=root

org.quartz.dataSource.DATA_SOURCE_NAME.password= 12345

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

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

org.quartz.jobStore.dataSource=DATA_SOURCE_NAME


建立數據庫:

導入quartz文檔中的mysql.sql建立好須要的數據表


故障恢復Demo:

   @Test

   //@Ignore

    public void recovery() {

        Scheduler scheduler  = null;

        try {

            scheduler = StdSchedulerFactory.getDefaultScheduler();

            scheduler.getListenerManager()

     .addJobListener(new MyJobListener() , KeyMatcher.keyEqualsnew JobKey("hello" , "MYJOB_GROUP")));

            scheduler.start();

        //調用schedule的shutdown()方法,這個時候job尚未執行完成,全部會被記錄到數據表qrtz_triggers中

            scheduler.shutdown();

        } catch (Exception e) {

            // TODO: handle exception

            e.printStackTrace();

        }


        try {

            //從新獲取schedule調度器,值得注意的是這裏獲取的調度器同上面的調度器不是同一個對象,而是一個新的調度器

            scheduler = StdSchedulerFactory.getDefaultScheduler(); 

            scheduler.start();

        //獲得group爲TestDB的數據中的記錄

            Set<TriggerKey> triggers = scheduler.getTriggerKeys(GroupMatcher.groupEquals ("TestDB" ));

            Iterator< TriggerKey> iterator = triggers.iterator();

            for (TriggerKey triggerKey : triggers) {

                Trigger trigger = scheduler.getTrigger(triggerKey);

//繼續執行沒執行完的trigger

                scheduler.rescheduleJob(triggerKey, trigger);

            }

            Thread. sleep(40000);

        } catch (SchedulerException e) {

            e.printStackTrace();

        } catch (InterruptedException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

    }

相關文章
相關標籤/搜索