Quartz排程器堵塞原理和解決

2021-08-25 16:18:43 字數 1599 閱讀 2283

quartz 排程器以多執行緒的方式執行排程任務jobdetail,預設執行緒池大小為10,也就是說若排程器中已有10個job在工作(執行緒沒有結束),那麼即使有jobdetail到了被觸發的時間,新的jobdetail不會被執行,也就是說阻塞的條件是,排程器中正在執行的jobdetail數量達到了設定值10。

舉乙個具體的例子:

a. 單一job

配置:joba 觸發時間為 每秒執行一次,每個job執行時間為30秒

執行:1、 10個joba將連續啟動

2、 到第10個joba啟動後,執行緒池中所有執行緒被耗盡,排程器出現了阻塞,即沒有新的joba啟動,儘管設定為每秒執行一次。

3、30秒後,將有1個以上joba執行完畢,在短時間內,新的10個joba又被啟動,再次進入2的阻塞狀態

2狀態可以稱做排程器阻塞狀態,沒有新的job能執行,導致一些諸如定時讀取資料的操作無法繼續下去。除非有joba執行完畢,新的joba才能被執行。實際執行中,假設排程器中有乙個joba執行緒的執行時間大於兩次啟動間隔,則經過若干次操作後,將耗盡所有10個執行緒資源,導致其他的排程任務阻塞。

b. 多個job(無狀態job)

在這個測試中,可以有多種不同的job(無狀態job),但它們均共享這10個執行緒,任何乙個job 執行緒執行時間大於兩次啟動間隔均有可能導致排程器被阻塞。例如:

配置:joba 觸發時間為 每秒執行一次,每個job執行時間為30秒;jobb 觸發時間為每秒執行一次,每次執行時間小於1秒

執行:1。joba和jobb相繼啟動

2。幾秒鐘後joba數量達到10,其間jobb被執行若干次,則新的joba和jobb均不能被啟動,排程器進入阻塞狀態

3。30秒後,joba(0-9)相繼執行完畢,新的joba和jobb均有機會被重新啟動,短時間內,再次進入2的阻塞狀態

如何解決排程器阻塞問題?

1、 延長可能需要較長時間執行的job的時間間隔,假設job執行時間最大時間為t1, 兩次任務執行間隔排程時間為d1, 則d1>t1

2、 使用有狀態排程任務statefuljob代替沒有狀態的job. 對於要求執行間隔時間盡可能短,又不希望造成阻塞的比較適合。可以同時有無狀態的排程任務joba,和有狀態的排程任務jobb,jobb堵塞後不會對joba造成影響,即讀報文的任務阻塞了,不會對排程器中其他任務造成影響,同時joba執行完後,可再次繼續下乙個任務。

如果joba執行時間較長的話,可能造成joba始終占用乙個執行緒資源。

3、注意:乙個排程器中如果有很多個job(joba,jobb,jobc...),其中有乙個很容易堵塞,則該job也會造成其他的job阻塞

執行緒池大小配置在org.quartz下的quartz.properties檔案中

org.quartz.threadpool.threadcount = 10

如若要修改執行緒池的大小,可以修改該檔案中的

org.quartz.threadpool.threadcount值。亦可建一org.quartz包,包下放置quartz.properties檔案,覆蓋掉quartz.jar中的配置

但是,修改執行緒池的大小並不能解決排程器阻塞問題,因為資源消耗的速度不及資源釋放的速度時,資源就會被耗盡。

Quartz排程器堵塞原理和解決

quartz 排程器以多執行緒的方式執行排程任務jobdetail,預設執行緒池大小為10,也就是說若排程器中已有10個job在工作 執行緒沒有結束 那麼即使有jobdetail到了被觸發的時間,新的jobdetail不會被執行,也就是說阻塞的條件是,排程器中正在執行的jobdetail數量達到了設...

Quartz排程器堵塞原理和解決

quartz 排程器以多執行緒的方式執行排程任務jobdetail,預設執行緒池大小為10,也就是說若排程器中已有10個job在工作 執行緒沒有結束 那麼即使有jobdetail到了被觸發的時間,新的jobdetail不會被執行,也就是說阻塞的條件是,排程器中正在執行的jobdetail數量達到了設...

Quartz排程器堵塞原理和解決

quartz 排程器以多執行緒的方式執行排程任務jobdetail,預設執行緒池大小為10,也就是說若排程器中已有10個job在工作 執行緒沒有結束 那麼即使有jobdetail到了被觸發的時間,新的jobdetail不會被執行,也就是說阻塞的條件是,排程器中正在執行的jobdetail數量達到了設...