1. 程式人生 > >Spring 3整合Quartz 2實現定時任務三:動態暫停 恢復 修改和刪除任務

Spring 3整合Quartz 2實現定時任務三:動態暫停 恢復 修改和刪除任務

前面我們已經完成了spring 3和quartz 2的整合以及動態新增定時任務,我們接著來完善它,使之能支援更多的操作,例如暫停、恢復、修改等。

在動態新增定時任務中其實已經涉及到了其中的一些程式碼,這裡我們再來細化的理一理。先來看一下我們初步要實現的目標效果圖,這裡我們只在記憶體中操作,並沒有把quartz的任何資訊儲存到資料庫,即使用的是RAMJobStore,當然如果你有需要,可以實現成JDBCJobStore,那樣任務資訊將會更全面,貌似還有專門的監控工具,不過本人沒有用過:

如上圖,我們要先列出計劃中的定時任務以及正在執行中的定時任務,這裡的正在執行中指的是任務已經觸發執行緒還沒執行完的情況。比如每天2點執行一個數據匯入操作,這個操作執行時間需要5分鐘,在這5分鐘之內這個任務才是執行中的任務。當任務正常時可以使用暫停按鈕,任務暫停時可以使用恢復按鈕。

trigger各狀態說明:

None:Trigger已經完成,且不會在執行,或者找不到該觸發器,或者Trigger已經被刪除 NORMAL:正常狀態 PAUSED:暫停狀態 COMPLETE:觸發器完成,但是任務可能還正在執行中 BLOCKED:執行緒阻塞狀態 ERROR:出現錯誤

計劃中的任務

指那些已經新增到quartz排程器的任務,因為quartz並沒有直接提供這樣的查詢介面,所以我們需要結合JobKey和Trigger來實現,核心程式碼:

Scheduler scheduler = schedulerFactoryBean.getScheduler();
GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
List<ScheduleJob> jobList = new ArrayList<ScheduleJob>();
for (JobKey jobKey : jobKeys) {
    List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
    for (Trigger trigger : triggers) {
        ScheduleJob job = new ScheduleJob();
        job.setJobName(jobKey.getName());
        job.setJobGroup(jobKey.getGroup());
        job.setDesc("觸發器:" + trigger.getKey());
        Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
        job.setJobStatus(triggerState.name());
        if (trigger instanceof CronTrigger) {
            CronTrigger cronTrigger = (CronTrigger) trigger;
            String cronExpression = cronTrigger.getCronExpression();
            job.setCronExpression(cronExpression);
        }
        jobList.add(job);
    }
}

上面程式碼中的jobList就是我們需要的計劃中的任務列表,需要注意一個job可能會有多個trigger的情況,在下面講到的立即執行一次任務的時候,會生成一個臨時的trigger也會出現在這。這裡把一個Job有多個trigger的情況看成是多個任務。我們前面包括在實際專案中一般用到的都是CronTrigger ,所以這裡我們著重處理了下CronTrigger的情況。

執行中的任務

實現和計劃中的任務類似,核心程式碼:

Scheduler scheduler = schedulerFactoryBean.getScheduler();
List<JobExecutionContext> executingJobs = scheduler.getCurrentlyExecutingJobs();
List<ScheduleJob> jobList = new ArrayList<ScheduleJob>(executingJobs.size());
for (JobExecutionContext executingJob : executingJobs) {
    ScheduleJob job = new ScheduleJob();
    JobDetail jobDetail = executingJob.getJobDetail();
    JobKey jobKey = jobDetail.getKey();
    Trigger trigger = executingJob.getTrigger();
    job.setJobName(jobKey.getName());
    job.setJobGroup(jobKey.getGroup());
    job.setDesc("觸發器:" + trigger.getKey());
    Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
    job.setJobStatus(triggerState.name());
    if (trigger instanceof CronTrigger) {
        CronTrigger cronTrigger = (CronTrigger) trigger;
        String cronExpression = cronTrigger.getCronExpression();
        job.setCronExpression(cronExpression);
    }
    jobList.add(job);
}

暫停任務

這個比較簡單,核心程式碼:

Scheduler scheduler = schedulerFactoryBean.getScheduler();
JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
scheduler.pauseJob(jobKey);

恢復任務

和暫停任務相對,核心程式碼:

Scheduler scheduler = schedulerFactoryBean.getScheduler();
JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
scheduler.resumeJob(jobKey);
刪除任務

刪除任務後,所對應的trigger也將被刪除

Scheduler scheduler = schedulerFactoryBean.getScheduler();
JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
scheduler.deleteJob(jobKey);

立即執行任務

這裡的立即執行,只會執行一次,方便測試時用。quartz是通過臨時生成一個trigger的方式來實現的,這個trigger將在本次任務執行完成之後自動刪除。trigger的key是隨機生成的,例如:DEFAULT.MT_4k9fd10jcn9mg。在我的測試中,前面的DEFAULT.MT是固定的,後面部分才隨機生成。

Scheduler scheduler = schedulerFactoryBean.getScheduler();
JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
scheduler.triggerJob(jobKey);
更新任務的時間表達式

更新之後,任務將立即按新的時間表達式執行:

Scheduler scheduler = schedulerFactoryBean.getScheduler();
TriggerKey triggerKey = TriggerKey.triggerKey(scheduleJob.getJobName(),
    scheduleJob.getJobGroup());
//獲取trigger,即在spring配置檔案中定義的 bean id="myTrigger"
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
//表示式排程構建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob
    .getCronExpression());
//按新的cronExpression表示式重新構建trigger
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
    .withSchedule(scheduleBuilder).build();
//按新的trigger重新設定job執行
scheduler.rescheduleJob(triggerKey, trigger);


到這裡,我們的spring3 整合quartz 2的定時任務功能終於是告一段落了,對常用的一些功能進行了實現,相信可以滿足一般專案的需求了。