雖然單個Quartz實例能給予我們很好的任務job調度能力,但它不能滿足典型的企業需求,如可伸縮性、高可靠性滿足。假如你需要故障轉移的能力並能運行日益增多的 Job,Quartz集群勢必成為你應用的一部分了。使用 Quartz 的集群能力可以更好的支持你的業務需求,並且即使是其中一台機器在最糟的時間掛掉了也能確保所有的 Job 得到執行。一個 Quartz 集群中的每個節點是一個獨立的 Quartz 應用,它又管理着其他的節點。也就是你必須對每個節點分別啟動或停止。不像許多應用服務器的集群,獨立的Quartz 節點並不與另一其的節點或是管理節點通信。Quartz 應用是通過數據庫表來感知到另一應用的。
Quartz集群配置很簡單,本篇配置基於我的上一篇文章https://www.cnblogs.com/hhhshct/p/9707710.html,只需要更改下quartz.properties即可,如下:
org.quartz.scheduler.instanceName = schedulerFactoryBean #調度器編號自動生成,集群中編號不可以重復,所以最好設成auto org.quartz.scheduler.instanceId = AUTO org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate org.quartz.jobStore.tablePrefix = QRTZ_ #開啟分布式部署 org.quartz.jobStore.isClustered = true #分布式節點有效性檢查時間間隔,單位:毫秒 org.quartz.jobStore.clusterCheckinInterval = 10000 org.quartz.jobStore.useProperties = false org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool org.quartz.threadPool.threadCount = 10 org.quartz.threadPool.threadPriority = 5 #配置是否啟動自動加載數據庫內的定時任務,默認true org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
啟動項目,端口號8081,作為第一個實例,可以看到之前我們加入的定時任務開始執行,修改端口號為8082,再啟動項目,作為第二個實例,可以看到沒有定時任務執行,然后我們手動down掉第一個實例,可以發現定時任務漂移到了我們的第二個實例,這樣就避免了單點故障而造成定時任務不執行的問題。
Quartz一點都不明確你是在同一台機器上運行所有節點,還是在不同的機器上運行所有節點。當集群是放置在不同的機器上時,我們稱之為水平集群。如果所有節點是跑在同一台機器的時候,我們稱之為垂直集群。對於垂直集群,存在着單點故障的問題。這對高可用性的應用來說是個壞消息,因為一旦機器宕掉了,所有的節點也就被有效的終止了。而當你運行水平集群時,一個嚴格的要求就是我們的時鍾時間必須要同步,以免出現離奇且不可預知的行為。假如時鍾沒能夠同步,Scheduler 實例將對其他節點的狀態產生混亂,造成難以估計得麻煩。至於如何解決這個問題,后續遇到再做研究了。