1.更新任務java
先前咱們在更新任務時,雖然更新了定時任務的執行時間,可是並無對參數進行更新,即便用context.getMergedJobDataMap().get(...)方法獲取到的參數仍是舊的。web
假設咱們更新了任務的時間表達式,任務已按新的時間表達式在執行,但在獲取到參數後發現時間表達式仍是原來的。spring
嘗試對參數進行更新,使用以下代碼:編程
JobDetail jobDetail = scheduler.getJobDetail(getJobKey(jobName, jobGroup)); //jobDetail = jobDetail.getJobBuilder().ofType(jobClass).build(); //更新參數 實際測試中發現沒法更新 JobDataMap jobDataMap = jobDetail.getJobDataMap(); jobDataMap.put(ScheduleJobVo.JOB_PARAM_KEY, param); jobDetail.getJobBuilder().usingJobData(jobDataMap);
發現沒法更新,試過其它幾個api發現都不行,沒有辦法,最後採用了先刪除任務再進行建立的方式來迂迴實現參數的更新。更新任務有直接修改方式和刪除修改方式,區別就在這裏。下面先刪後加的方式更新Jobapi
Scheduler scheduler = schedulerFactoryBean.getScheduler(); JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup()); scheduler.deleteJob(jobKey); //修改cronTrigger //根據TriggerKey和Trigger從新添加一個Job到scheduler scheduler.addJob...
2.任務的同步和異步tomcat
在定時任務運行時更新是沒有辦法改變同步和異步的app
同步和異步在quartz 2.2的版本中對於使用者來講區別只在因而否在job類上添加了@DisallowConcurrentExecution註解webapp
整合使用時,碰到的一些問題:異步
1、更新任務時參數問題。也就是前面說的沒法更新任務中傳入的參數。分佈式
2、同步或異步在定時任務運行時修改是不能改變的,這個在前面也提到了。
3、在定時任務運行時修改,可能會該讓任務長時間處於線程阻塞狀態,即BLOCKED狀態,即便你的任務中只有簡單的一行System.out輸出。要使它恢復也很簡單,刪除重建便可。
4、定時任務運行兩次的問題。這個也是網上傳的最多的問題,這裏來着重的說一下。
網上流傳引發該問題的緣由目前主要有兩個說法:
1 spring配置文件加載了屢次,致使quartz的bean被實例化屢次而致使任務屢次執行。
2 tomcat的webapps目錄問題。tomcat運行時加載了兩次配置文件致使任務屢次執行。
這兩個說法在個人demo中應該並不存在,但爲了驗證我也嘗試了下。
不使用tomcat,在main方法中用編程的方式啓動spring,甚至不使用spring,直接用quartz官方給出的代碼:
try { // Grab the Scheduler instance from the Factory Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); // and start it off scheduler.start(); scheduler.shutdown(); } catch (SchedulerException se) { se.printStackTrace(); }
問題仍是存在,這就說明不是配置文件加載的問題了,這應該是quartz自己存在的一個bug,並且這個屢次運行是頗有規律的,基本按以下套路走:
定爲5秒運行一次,一切正常,沒有屢次執行現象發生。
定爲10秒運行一次,一切正常,沒有屢次執行現象發生。
定爲29秒運行一次,運行時一次正常,一次不正常。
定爲59秒運行一次,運行時一次正常,一次不正常。
以上是我實測得出的,再長時間就沒測了,畢竟太耗時。在有運行兩次的現象時都是間隔的,即一次正常一次不正常這種方式。
既然推斷是quartz自己存在bug,那咱們又要如何解決這個問題了?
其實在我我的看來,這個問題是可有可無的,爲何說可有可無呢?這就涉及到你項目業務設計的是否完善,代碼是否健壯了。
一個設計良好的業務方法,特別是那些供外部調用的接口或方法,應該都支持冪等性,何爲冪等性?即這個方法一樣的參數至少在一個時間區間內,我調用1次和調用10次100次,結果都是同樣的。
支持了冪等性,前面說的運行兩次的狀況是否是就可有可無了?在有些定時任務爲分佈式設計的系統(後面會探討)中,爲了確保定時任務的執行甚至會故意人爲的去調用兩次。
固然支持冪等性最好是在進入方法時就判斷,發現已經執行過期就當即返回而不是真的再去一樣的結果再執行一遍,以節省資源。