Quartz Cluster

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chen517611641/article/details/88930091

基于数据库JobStore的Quartz Cluster实现

ClusterManager
如果开启cluster的话,ClusterManager线程会运行,参见JobStroeSupport#scheduleStarted();
ClusterCheck这个check是check啥,参看JobStoreSupport#doCheckIn(),检查scheduler是否失效,scheduler_state表
当前scheduler实例的ClusterManger线程check自己的scheduler实例

org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 20000

配置要点:

  1. org.quartz.scheduler.instanceName 的值集群中的所有节点配置一样的值
  2. org.quartz.scheduler.instanceId = AUTO 一个集群中所有的节点必须都不一样
  3. 所有节点使用同一个数据库
  4. 所有文件使用同一个quartz.properties的拷贝

Semaphore接口

LockHandler

org.quartz.jobStore.lockHandler
org.quartz.jobStore.lockHandler.class

JobStoreCMT的executeInLock方法有典型的用法执行增删改方法时,都是executeInLock,在这里先拿到锁,执行完毕后,释放锁;

目前定义在JobStoreSupport中两种类型的锁,Trigger_Access锁Trigger表和STATE_ACCESS

Customizing StdRowLockSemaphore

org.quartz.jobStore.lockHandler.class = org.quartz.impl.jdbcjobstore.StdRowLockSemaphore
org.quartz.jobStore.lockHandler.maxRetry = 7     # Default is 3
org.quartz.jobStore.lockHandler.maxRetry = 3000  # Default is 1000 millis

quartz的恢复机制,单机和集群,在JobStoreSupport里

In-progress Jobs marked “recoverable” are automatically re-executed after a scheduler fails. This means some of the job’s “work” will be executed twice.

This means the job should be coded in such a way that its work is idempotent.

JTA

org.quartz.scheduler.wrapJobExecutionInUserTransaction

如果设置为true,执行job的时候,会将job的execute放到UserTransaction中间执行;
如果设置为false,则只有加了@ExecuteInJTATransaction的Job才会放到事物中间执行;

org.quartz.scheduler.userTransactionURL:设置UserTransaction的JNDI

JobRunShell
JTAJobRunShell

JTAAnnotationAwareJobRunShellFactory
JTAJobRunShellFactory

JDBC-JobStoreTX && JDBC-JobStoreCMT

JobStoreTx自己管理事务
JobStoreCMT假设Connection已经参与到事务中,不用手动尝试commit or rollback 事务,让容器事务管理器来管理
同时可以给JobStoreCMT提供一个不受事务管理器控制的Connection,用于进行一些查询操作,优化速度;具体可以参看在JobStoreCMT#getNonManagerdTxConnection在哪些方法中调用了。

扫描二维码关注公众号,回复: 5726782 查看本文章

JobStoreTx配置

org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass
org.quartz.jobStore.dataSource
org.quartz.jobStore.driverDelegateInitString

org.quartz.jobStore.dontSetAutoCommitFalse
org.quartz.jobStore.txIsolationLevelSerializable

org.quartz.jobStore.tablePrefix
org.quartz.jobStore.useProperties

org.quartz.jobStore.isClustered
org.quartz.jobStore.clusterCheckinInterval

org.quartz.jobStore.misfireThreshold
org.quartz.jobStore.maxMisfiresToHandleAtATime

org.quartz.jobStore.selectWithLockSQL
org.quartz.jobStore.acquireTriggersWithinLock
org.quartz.jobStore.lockHandler.class

JobStoreCMT配置

org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreCMT
org.quartz.jobStore.driverDelegateClass: database dialects
org.quartz.jobStore.dataSource:指定一个Application Server DataSource
org.quartz.jobStore.nonManagedTXDataSource:执行非必要的事务的操作的时候使用此数据源
org.quartz.jobStore.driverDelegateInitString:初始化JDBCDelegate的时候,StdJDBCDelegate构造函数上的参数
给Connection设置的属性
org.quartz.jobStore.dontSetAutoCommitFalse:是否将从Datasource获取到的Connection,的autoCommit属性设置为false;小众属性;
org.quartz.jobStore.dontSetNonManagedTXConnectionAutoCommitFalse
org.quartz.jobStore.txIsolationLevelSerializable

org.quartz.jobStore.tablePrefix:Quartz系统表前缀
org.quartz.jobStore.useProperties:在Job定义的时候,可以在Job类上添加@PersistJobAfterExecution注解,这样QRTZ_Job_DETAILS表中的JOB_DATA字段就会有值,值为Job的JobDataMap序列化之后的内容;useProperties属性可以让保存JobDataMap保存为name-value对;

org.quartz.jobStore.isClustered:是否开启集群
org.quartz.jobStore.clusterCheckinInterval:ClusterManager执行检查的间隔

org.quartz.jobStore.misfireThreshold:容忍错过时间的阀值,超过Trigger的指定的触发时间在这个值之内,不算是misfire;
org.quartz.jobStore.maxMisfiresToHandleAtATime:JobStore一次性获取错过触发的Trigger的最大数。如果设置一次性处理太多会导致数据库表锁住太长时间,妨碍到其他错过触发的Trigger;

org.quartz.jobStore.selectWithLockSQL
org.quartz.jobStore.acquireTriggersWithinLock:获取Trigger的时候是否加锁,JobStoreSupport#acquireNextTriggers方法
org.quartz.jobStore.lockHandler.class:JobStore里大部分的增删改操作都需要加锁

DataSource配置方法

org.quartz.dataSource.NAME.driver
org.quartz.dataSource.NAME.URL
org.quartz.dataSource.NAME.user
org.quartz.dataSource.NAME.password
org.quartz.dataSource.NAME.maxConnections
org.quartz.dataSource.NAME.validationQuery
org.quartz.dataSource.NAME.idleConnectionValidationSeconds
org.quartz.dataSource.NAME.validateOnCheckout
org.quartz.dataSource.NAME.discardIdleConnectionsSeconds

ConnectionProvider配置

org.quartz.dataSource.NAME.connectionProvider.class
org.quartz.dataSource.myCustomDS.connectionProvider.class = com.foo.FooConnectionProvider
org.quartz.dataSource.myCustomDS.someStringProperty = someValue
org.quartz.dataSource.myCustomDS.someIntProperty = 5

注意2.3.0版本的quartz 提供的HikariCpPollingConnectionProvider因为没有提供无参数构造方法,没有使用ClassLoaderHelper实例化,导致没法用,想用可以自己打包个版本

如果是配置容器事务,配置容器数据源的话

org.quartz.dataSource.NAME.jndiURL
org.quartz.dataSource.NAME.java.naming.factory.initial
org.quartz.dataSource.NAME.java.naming.provider.url
org.quartz.dataSource.NAME.java.naming.security.principal
org.quartz.dataSource.NAME.java.naming.security.credentials

猜你喜欢

转载自blog.csdn.net/chen517611641/article/details/88930091