使用JDBC-JobStore配置群集
Quartz的集群功能通过故障转移和负载平衡功能为您的调度程序带来高可用性和可扩展性。
目前,群集仅适用于JDBC-Jobstore(JobStoreTX或JobStoreCMT),并且基本上通过使群集的每个节点共享相同的数据库来工作。
负载平衡自动发生,群集的每个节点都尽可能快地触发jobs。当Triggers的触发时间发生时,获取它的第一个节点(通过在其上放置一个锁定)是将触发它的节点。
每次射击只能有一个节点开火。我的意思是,如果工作有一个重复的Triggers,告诉它每10秒钟发射一次,那么在12:00:00,正好一个节点将运行这个工作,在12:00:10,一个节点将运行作业等。它不一定是每次相同的节点 - 它或多或少是随机的,哪个节点运行它。负载平衡机制对于繁忙的调度器(大量的Triggers)是近似随机的,但是对于非忙(例如,很少的Triggers)调度器而言,有利于同一个节点。
当其中一个节点在执行一个或多个作业期间失败时发生故障切换。当节点出现故障时,其他节点会检测到该状况并识别数据库中在故障节点内正在进行的作业。任何标记为恢复的作业(在JobDetail上都具有“请求恢复”属性)将被剩余的节点重新执行。没有标记为恢复的作业将在下一次相关的Triggers触发时简单地被释放以执行。
集群功能最适合扩展长时间运行和/或cpu密集型作业(通过多个节点分配工作负载)。如果需要扩展以支持数千个短期运行(例如1秒)作业,则可以考虑通过使用多个不同的调度程序(包括HA的多个群集调度程序)对作业集进行分区。调度程序使用集群范围的锁,这种模式会在添加更多节点(超过三个节点 - 取决于数据库的功能等)时降低性能。
通过将“org.quartz.jobStore.isClustered”属性设置为“true”来启用聚类。集群中的每个实例都应该使用相同的quartz.properties文件。这样做的例外是使用相同的属性文件,具有以下允许的异常:不同的线程池大小,以及“org.quartz.scheduler.instanceId”属性的不同值。集群中的每个节点必须具有唯一的instanceId,通过将“AUTO”作为此属性的值,可以轻松完成(不需要不同的属性文件)。有关更多信息,请参阅有关JDBC-JobStore的配置属性的信息。
不要在单独的机器上运行群集,除非它们的时钟使用某种形式的时间同步服务(守护进程)进行同步,而这些时间同步服务(守护进程)运行非常有限(时钟必须在彼此之间)。如果您不熟悉如何执行此操作,请参阅http://www.boulder.nist.gov/timefreq/service/its.htm。
不要针对任何其他实例运行(start()ed)的同一组数据库表启动(scheduler.start())非集群实例。您可能会收到严重的数据损坏,一定会遇到不正常的行为。
集群调度程序的示例属性
#============================================================================
# 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