一、Quartz概述:
Quartz是一個完全由Java編寫的開源任務調度的框架,通過觸發器設置作業定時運行規則,控制作業的運行時間。其中quartz集群通過故障切換和負載平衡的功能,能給調度器帶來高可用性和伸縮性。主要用來執行定時任務,如:定時發送信息、定時生成報表等等。
二、相關術語:
三、Quartz的體系結構簡介:
Quartz框架主要核心組件包括調度器、觸發器、作業。調度器作為作業的總指揮,觸發器作為作業的操作者,作業為應用的功能模塊。其關系如下圖所示:
Job為作業的接口,為任務調度的對象;JobDetail用來描述Job的實現類及其它相關的靜態信息;Trigger做為作業的定時管理工具,一個Trigger只能對應一個作業實例,而一個作業實例可對應多個觸發器;Scheduler做為定時任務容器,是quartz最上層的東西,它提攜了所有觸發器和作業,使它們協調工作,每個Scheduler都存有JobDetail和Trigger的注冊,一個Scheduler中可以注冊多個JobDetail和多個Trigger。
1、Job
Job是一個接口,只有一個方法void execute(JobExecutionContext context),被調度的作業(類)需實現該接口中execute()方法,JobExecutionContext類提供了調度上下文的各種信息。每次執行該Job均重新創建一個Job實例,如:
- public class DDNJob implements Job{
- public void execute(JobExecutionContext arg0) throws JobExecutionException {
- perform();
- }
- public void perform(){ //執行報表統計入口函數
- //業務邏輯
- System.out.println("自動DDN預授權開始執行-------------執行時間:"+new Date());
- }
- }
注:DDNJob類為需要定時執行的類,execute為定時執行的方法。一個定時任務對應一個Job實現類。
2、JobDetail
Quartz在每次執行Job時,都重新創建一個Job實例,所以它不直接接受一個Job的實例,相反它接收一個Job實現類,以便運行時通過newInstance()的反射機制實例化Job。因此需要通過一個類來描述Job的實現類及其它相關的靜態信息,如Job名字、描述、關聯監聽器等信息,JobDetail承擔了這一角色。JobDetail 用來保存我們作業的詳細信息。一個JobDetail可以有多個Trigger,但是一個Trigger只能對應一個JobDetail,
示例:
- 1. JobDetail jobDetail = new JobDetail("myJob","myGroup",DDNJob.class)
- 2. 說明:
- 3. myJob:job 名
- 4. myGroup:job 組(為'null'時,使用缺省的組sched.DEFAULT_GROUP)
- 5. DDNJob.class:要被執行的Java類。
運用spring集成的MethodInvokingJobDetailFactoryBean時spring能自動生成符合quartz要去的JobDetail。
Spring中applicationContext.xml配置如下:
- <!-- detail任務描述 -->
- <bean name="DDNDetail"
- class="com.mangocity.mpm.common.autoDDN.MethodInvokingJobDetailFactoryBean">
- <property name="targetObject" value="DDNJob" />
- <property name="concurrent" value="false"/>(並發執行)
- <property name="shouldRecover" value="true"/>
- </bean>
3、Trigger
Trigger是一個類,描述觸發Job執行的時間觸發規則。主要有SimpleTrigger和 CronTrigger這兩個子類。當僅需觸發一次或者以固定時間間隔周期執行,SimpleTrigger是最適合的選擇;而CronTrigger則 可以通過Cron表達式定義出各種復雜時間規則的調度方案:如每早晨9:00執行,周一、周三、周五下午5:00執行等;Spring中applicationContext.xml配置如下:
SimpleTrigger使用示例:
- // Initiate SimpleTrigger with its name and group name
- SimpleTrigger simpleTrigger = new SimpleTrigger("simpleTrigger","triggerGroup1");
- // set its start up time
- simpleTrigger.setStartTime(new Date(System.currentTimeMillis()));
- // set the interval, how often the job should run (10 seconds here)
- simpleTrigger.setRepeatInterval(10000);
- // set the number of execution of this job, set to 10 times.
- simpleTrigger.setRepeatCount(10);
通過Spring配置,jobDetail為配置的Job描述,startDelay為系統啟動執行延遲時間,repeatCount為調用次數,repeatInterval為Job觸發時間間隔。
- <bean id="DDNSimpletrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
- <property name="jobDetail" ref="DDNDetail"/>
- <property name="startDelay" value="1"/>
- <property name="repeatCount" value="100"/>
- <property name="repeatInterval" value="1000"/>
- </bean>
CronTrigger使用示例:
- // Initiate CronTrigger with its name and group name
- CronTrigger cronTrigger = new CronTrigger("cronTrigger","triggerGroup2");
- try {
- // setup CronExpression
- CronExpression cexp = new CronExpression("0/5 * * * * ?");
- // Assign the CronExpression to CronTrigger
- cronTrigger.setCronExpression(cexp);
- } catch (Exception e) {
- e.printStackTrace();
- }
通過Spring配置,jobDetail為配置的Job描述,cronExpression為Job的運行規則,具體見附錄部分內容。
- <bean id="DDNCrontrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
- <property name="jobDetail" ref="DDNDetail"/>
- <property name="cronExpression" value="0/5 * * ? * * *"/>
- </bean>
4、Scheduler
Scheduler負責管理Quartz的運行環境,Quartz它是基於多線程架構的,它啟動的時候會初始化一套線程,這套線程會用來執行一些預置的作業。Trigger和JobDetail可以注冊到Scheduler中;Scheduler可以將Trigger綁定到某一JobDetail中,這樣當Trigger觸發時,對應的Job就被執行。 Scheduler擁有一個SchedulerContext,它類似於ServletContext,保存着Scheduler上下文信息,Job和Trigger都可以訪問SchedulerContext內的信息。Scheduler使用一個線程池作為任務運行的基礎設施,任務通過共享線程池中的線程提高運行效率。 應用示例:
- SchedulerFactory schedulerFactory = new StdSchedulerFactory();
- // Retrieve a scheduler from schedule factory
- Scheduler scheduler = schedulerFactory.getScheduler();
- …
- // schedule a job with JobDetail and Trigger
- scheduler.scheduleJob(jobDetail, simpleTrigger);
- // start the scheduler
- scheduler.start();
Spring中applicationContext.xml配置:
- <!-- 調度器 -->
- <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
- <property name="dataSource">
- <ref bean="dataSource"/>
- </property>
- <property name="triggers">
- <list>
- <!-- 觸發器列表 -->
- <!-- <ref bean="DDNcronTrigger" /> -->
- <ref bean="DDNSimpletrigger" />
- </list>
- </property>
- <property name="configLocation" value="classpath:quartz.properties" />
- </bean>
其中,dataSource為數據源配置,triggers為觸發器列表配置,可以同時包含多個trigger,configLocation為quartz配置文件quartz.properties加載路徑。
四、總結:
我們不只有一種兩種方法來實現我們的定時任務,就我知道的出了我們的quartz框架之外,我們spring也自己封裝有自己的定時器,再加上各種開源的插件。那我工作的公司來說,我們用windows服務來完成這個定時任務,萬變不離其宗,理解了他們的原理以及精髓,我們就可以去創新,去寫出符合自己要求的工具了!