Quartz的集群功能通過故障轉(zhuǎn)移和負(fù)載平衡功能為您的調(diào)度程序帶來高可用性和可擴展性。
目前,群集僅適用于JDBC-Jobstore(JobStoreTX或JobStoreCMT),并且基本上通過使群集的每個節(jié)點共享相同的數(shù)據(jù)庫來工作。
負(fù)載平衡自動發(fā)生,群集的每個節(jié)點都盡可能快地觸發(fā)jobs。當(dāng)Triggers的觸發(fā)時間發(fā)生時,獲取它的第一個節(jié)點(通過在其上放置一個鎖定)是將觸發(fā)它的節(jié)點。
每次射擊只能有一個節(jié)點開火。我的意思是,如果工作有一個重復(fù)的Triggers,告訴它每10秒鐘發(fā)射一次,那么在12:00:00,正好一個節(jié)點將運行這個工作,在12:00:10,一個節(jié)點將運行作業(yè)等。它不一定是每次相同的節(jié)點 - 它或多或少是隨機的,哪個節(jié)點運行它。負(fù)載平衡機制對于繁忙的調(diào)度器(大量的Triggers)是近似隨機的,但是對于非忙(例如,很少的Triggers)調(diào)度器而言,有利于同一個節(jié)點。
當(dāng)其中一個節(jié)點在執(zhí)行一個或多個作業(yè)期間失敗時發(fā)生故障切換。當(dāng)節(jié)點出現(xiàn)故障時,其他節(jié)點會檢測到該狀況并識別數(shù)據(jù)庫中在故障節(jié)點內(nèi)正在進(jìn)行的作業(yè)。任何標(biāo)記為恢復(fù)的作業(yè)(在JobDetail上都具有“請求恢復(fù)”屬性)將被剩余的節(jié)點重新執(zhí)行。沒有標(biāo)記為恢復(fù)的作業(yè)將在下一次相關(guān)的Triggers觸發(fā)時簡單地被釋放以執(zhí)行。
集群功能最適合擴展長時間運行和/或cpu密集型作業(yè)(通過多個節(jié)點分配工作負(fù)載)。如果需要擴展以支持?jǐn)?shù)千個短期運行(例如1秒)作業(yè),則可以考慮通過使用多個不同的調(diào)度程序(包括HA的多個群集調(diào)度程序)對作業(yè)集進(jìn)行分區(qū)。調(diào)度程序使用集群范圍的鎖,這種模式會在添加更多節(jié)點(超過三個節(jié)點 - 取決于數(shù)據(jù)庫的功能等)時降低性能。
通過將“org.quartz.jobStore.isClustered”屬性設(shè)置為“true”來啟用聚類。集群中的每個實例都應(yīng)該使用相同的quartz.properties文件。這樣做的例外是使用相同的屬性文件,具有以下允許的異常:不同的線程池大小,以及“org.quartz.scheduler.instanceId”屬性的不同值。集群中的每個節(jié)點必須具有唯一的instanceId,通過將“AUTO”作為此屬性的值,可以輕松完成(不需要不同的屬性文件)。有關(guān)更多信息,請參閱有關(guān)JDBC-JobStore的配置屬性的信息。
不要在單獨的機器上運行群集,除非它們的時鐘使用某種形式的時間同步服務(wù)(守護(hù)進(jìn)程)進(jìn)行同步,而這些時間同步服務(wù)(守護(hù)進(jìn)程)運行非常有限(時鐘必須在彼此之間)。如果您不熟悉如何執(zhí)行此操作,請參閱http://www.boulder.nist.gov/timefreq/service/its.htm。
不要針對任何其他實例運行(start()ed)的同一組數(shù)據(jù)庫表啟動(scheduler.start())非集群實例。您可能會收到嚴(yán)重的數(shù)據(jù)損壞,一定會遇到不正常的行為。
集群調(diào)度程序的示例屬性
#============================================================================
# Configure Main Scheduler Properties
#============================================================================
org.quartz.scheduler.instanceName = MyClusteredScheduler
org.quartz.scheduler.instanceId = AUTO
#============================================================================
# Configure ThreadPool
#============================================================================
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 25
org.quartz.threadPool.threadPriority = 5
#============================================================================
# Configure JobStore
#============================================================================
org.quartz.jobStore.misfireThreshold = 60000
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
org.quartz.jobStore.useProperties = false
org.quartz.jobStore.dataSource = myDS
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 20000
#============================================================================
# Configure Datasources
#============================================================================
org.quartz.dataSource.myDS.driver = oracle.jdbc.driver.OracleDriver
org.quartz.dataSource.myDS.URL = jdbc:oracle:thin:@polarbear:1521:dev
org.quartz.dataSource.myDS.user = quartz
org.quartz.dataSource.myDS.password = quartz
org.quartz.dataSource.myDS.maxConnections = 5
org.quartz.dataSource.myDS.validationQuery=select 0 from dual
更多建議: