簡體   English   中英

Quartz Job由每台群集計算機同時執行多次,而不是整個群集由一台計算機一次執行

[英]Quartz Job executed multiple times simultaneously by each cluster machine, rather than one time by one machine for the entire cluster

目標: *對於三個節點的群集,每10分鍾運行一次Job1,對於同一群集,Job2每5分鍾運行一次。 每個作業都會生成一封電子郵件; 因此,在10:55 am,我應該只從集群收到一封Job2電子郵件,在11:00 am,我應該從集群收到一封Job1電子郵件和一封Job2電子郵件,在11:05 am,我應該只從集群收到一封Job2電子郵件,等等...

問題: * Job1在群集中的每個節點上每10分鍾運行多次,而Job2相同(每5分鍾除外)。 這導致了不止一個或兩個電子郵件。

配置: *三節點Linux集群*每台計算機NTP已配置並與時間同步* Oracle DB * Quartz v2.2.0(集群模式)*通過CronTrigger配置的作業*每個節點都有一個相同的獨立Java應用程序實例,該實例在Java應用程序會以集群模式實例化石英調度程序的實例。 *每台計算機上的quartz.properties文件是相同的。

我已經研究了所有明顯的潛在原因,但沒有任何解釋或提出解決辦法。 我什至嘗試在作業中插入一個10秒的人工睡眠指令,以確保它不會在一秒鍾內完成。 請在下面找到相關的工件(quartz.properties和日志輸出)。 任何幫助將不勝感激!

工件1:

============================================================================
============================================================================
Q U A R T Z   ---   P R O P E R T I E S 
==================

    #============================================================================
    # Configure Main Scheduler Properties  
    #============================================================================

    org.quartz.scheduler.instanceName: MyQrtzScheduler
    org.quartz.scheduler.instanceId: AUTO

    org.quartz.scheduler.skipUpdateCheck: true

    #============================================================================
    # Configure ThreadPool  
    #============================================================================

    org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
    org.quartz.threadPool.threadCount: 1
    org.quartz.threadPool.threadPriority: 5

    #============================================================================
    # Configure JobStore  
    #============================================================================

    org.quartz.jobStore.misfireThreshold: 2592000000

    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=60000

    #============================================================================
    # Other Example Delegates
    #============================================================================
    #org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.DB2v6Delegate
    #org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.DB2v7Delegate
    #org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.DriverDelegate
    #org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.HSQLDBDelegate
    #org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.MSSQLDelegate
    #org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PointbaseDelegate
    #org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
    #org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
    #org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.WebLogicDelegate
    #org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
    #org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.oracle.WebLogicOracleDelegate

    #============================================================================
    # Configure Datasources  
    #============================================================================

    org.quartz.dataSource.myDS.driver: oracle.jdbc.driver.OracleDriver
    org.quartz.dataSource.myDS.URL: jdbc:oracle:thin:@myServer:myPort:blah
    org.quartz.dataSource.myDS.user: myDBUser
    org.quartz.dataSource.myDS.password: myDBPassword
    org.quartz.dataSource.myDS.maxConnections: 2
    org.quartz.dataSource.myDS.validationQuery: select 0

    #============================================================================
    # Configure Plugins 
    #============================================================================

    org.quartz.plugin.shutdownHook.class: org.quartz.plugins.management.ShutdownHookPlugin
    org.quartz.plugin.shutdownHook.cleanShutdown: true
    org.quartz.plugin.triggerHistory.class=org.quartz.plugins.history.LoggingTriggerHistoryPlugin
    org.quartz.plugin.jobHistory.class=org.quartz.plugins.history.LoggingJobHistoryPlugin

工件2:

============================================================================
============================================================================
L O G  ---  O U T P U T
==================
    2015-01-29 12:56:16,602 [main]  INFO com.mycompany.myapp.jobs.QuartzHelper - Initializing Quartz scheduler...
    2015-01-29 12:56:16,829 [main]  INFO org.quartz.impl.StdSchedulerFactory - Using default implementation for ThreadExecutor
    2015-01-29 12:56:16,855 [main]  INFO org.quartz.core.SchedulerSignalerImpl - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
    2015-01-29 12:56:16,855 [main]  INFO org.quartz.core.QuartzScheduler - Quartz Scheduler v.2.2.0 created.
    2015-01-29 12:56:16,857 [main]  INFO org.quartz.plugins.management.ShutdownHookPlugin - Registering Quartz shutdown hook.
    2015-01-29 12:56:16,859 [main]  INFO org.quartz.impl.jdbcjobstore.JobStoreTX - Using db table-based data access locking (synchronization).
    2015-01-29 12:56:16,864 [main]  INFO org.quartz.impl.jdbcjobstore.JobStoreTX - JobStoreTX initialized.
    2015-01-29 12:56:16,865 [main]  INFO org.quartz.core.QuartzScheduler - Scheduler meta-data: Quartz Scheduler (v2.2.0) 'MyQrtzScheduler' with instanceId 'node1_1422554176832'
      Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
      NOT STARTED.
      Currently in standby mode.
      Number of jobs executed: 0
      Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 1 threads.
      Using job-store 'org.quartz.impl.jdbcjobstore.JobStoreTX' - which supports persistence. and is clustered.

    2015-01-29 12:56:16,865 [main]  INFO org.quartz.impl.StdSchedulerFactory - Quartz scheduler 'MyQrtzScheduler' initialized from specified file: '/my/install/directory/quartz.properties'
    2015-01-29 12:56:16,866 [main]  INFO org.quartz.impl.StdSchedulerFactory - Quartz scheduler version: 2.2.0
    2015-01-29 12:56:16,866 [main]  INFO com.mycompany.myapp.jobs.QuartzHelper - Quartz scheduler initialized successfully.

    2015-01-29 12:59:53,450 [MyQrtzScheduler_QuartzSchedulerThread] DEBUG org.quartz.core.QuartzSchedulerThread - batch acquisition of 1 triggers
    2015-01-29 13:00:00,007 [MyQrtzScheduler_QuartzSchedulerThread] DEBUG org.quartz.impl.jdbcjobstore.StdRowLockSemaphore - Lock 'TRIGGER_ACCESS' is desired by: MyQrtzScheduler_QuartzSchedulerThread
    2015-01-29 13:00:00,008 [MyQrtzScheduler_QuartzSchedulerThread] DEBUG org.quartz.impl.jdbcjobstore.StdRowLockSemaphore - Lock 'TRIGGER_ACCESS' is being obtained: MyQrtzScheduler_QuartzSchedulerThread
    2015-01-29 13:00:00,809 [MyQrtzScheduler_QuartzSchedulerThread] DEBUG org.quartz.impl.jdbcjobstore.StdRowLockSemaphore - Lock 'TRIGGER_ACCESS' given to: MyQrtzScheduler_QuartzSchedulerThread
    2015-01-29 13:00:00,836 [MyQrtzScheduler_QuartzSchedulerThread] DEBUG org.quartz.impl.jdbcjobstore.StdRowLockSemaphore - Lock 'TRIGGER_ACCESS' returned by: MyQrtzScheduler_QuartzSchedulerThread
    2015-01-29 13:00:00,839 [MyQrtzScheduler_QuartzSchedulerThread] DEBUG org.quartz.simpl.PropertySettingJobFactory - Producing instance of Job 'node2_1422546730757.Job1', class=com.mycompany.myapp.job.Job1
    2015-01-29 13:00:00,851 [MyQrtzScheduler_Worker-1]  INFO org.quartz.plugins.history.LoggingTriggerHistoryPlugin - Trigger node2_1422546730757.Job1Trigger fired job node2_1422546730757.Job1 at:  13:00:00 01/29/2015
    2015-01-29 13:00:00,852 [MyQrtzScheduler_Worker-1]  INFO org.quartz.plugins.history.LoggingJobHistoryPlugin - Job node2_1422546730757.Job1 fired (by trigger node2_1422546730757.Job1Trigger) at:  13:00:00 01/29/2015
    2015-01-29 13:00:00,852 [MyQrtzScheduler_Worker-1] DEBUG org.quartz.core.JobRunShell - Calling execute on job node2_1422546730757.Job1
    2015-01-29 13:00:00,853 [MyQrtzScheduler_Worker-1]  INFO com.mycompany.myapp.job.Job1 - ***Executing Inbound File SLA Job...
    2015-01-29 13:00:02,054 [MyQrtzScheduler_Worker-1]  INFO com.mycompany.myapp.job.Job1 - ***Inbound File SLA Job: No SLA breaches found...
    2015-01-29 13:00:02,150 [MyQrtzScheduler_Worker-1]  INFO com.mycompany.myapp.job.Job1 - Job1 completed successfully in [1297ms]; sleeping [63703ms] to meet the required minimum runtime for quartz-jobs
    2015-01-29 13:00:24,881 [QuartzScheduler_MyQrtzScheduler-node1_1422554176832_ClusterManager] DEBUG org.quartz.impl.jdbcjobstore.JobStoreTX - ClusterManager: Check-in complete.
    2015-01-29 13:01:05,862 [MyQrtzScheduler_Worker-1]  INFO com.mycompany.myapp.job.Job1 - Job1 sleep-delay completed.
    2015-01-29 13:01:05,864 [MyQrtzScheduler_Worker-1]  INFO org.quartz.plugins.history.LoggingJobHistoryPlugin - Job node2_1422546730757.Job1 execution complete at  13:01:05 01/29/2015 and reports: SUCCESS
    2015-01-29 13:01:05,865 [MyQrtzScheduler_Worker-1]  INFO org.quartz.plugins.history.LoggingTriggerHistoryPlugin - Trigger node2_1422546730757.Job1Trigger completed firing job node2_1422546730757.Job1 at  13:01:05 01/29/2015 with resulting trigger instruction code: DO NOTHING
    2015-01-29 13:01:05,868 [MyQrtzScheduler_Worker-1] DEBUG org.quartz.impl.jdbcjobstore.StdRowLockSemaphore - Lock 'TRIGGER_ACCESS' is desired by: MyQrtzScheduler_Worker-1
    2015-01-29 13:01:05,869 [MyQrtzScheduler_Worker-1] DEBUG org.quartz.impl.jdbcjobstore.StdRowLockSemaphore - Lock 'TRIGGER_ACCESS' is being obtained: MyQrtzScheduler_Worker-1
    2015-01-29 13:01:05,872 [MyQrtzScheduler_Worker-1] DEBUG org.quartz.impl.jdbcjobstore.StdRowLockSemaphore - Lock 'TRIGGER_ACCESS' given to: MyQrtzScheduler_Worker-1
    2015-01-29 13:01:05,880 [MyQrtzScheduler_Worker-1] DEBUG org.quartz.impl.jdbcjobstore.StdRowLockSemaphore - Lock 'TRIGGER_ACCESS' returned by: MyQrtzScheduler_Worker-1
    2015-01-29 13:01:05,915 [MyQrtzScheduler_QuartzSchedulerThread] DEBUG org.quartz.core.QuartzSchedulerThread - batch acquisition of 1 triggers
    2015-01-29 13:01:05,917 [MyQrtzScheduler_QuartzSchedulerThread] DEBUG org.quartz.impl.jdbcjobstore.StdRowLockSemaphore - Lock 'TRIGGER_ACCESS' is desired by: MyQrtzScheduler_QuartzSchedulerThread
    2015-01-29 13:01:05,918 [MyQrtzScheduler_QuartzSchedulerThread] DEBUG org.quartz.impl.jdbcjobstore.StdRowLockSemaphore - Lock 'TRIGGER_ACCESS' is being obtained: MyQrtzScheduler_QuartzSchedulerThread
    2015-01-29 13:01:05,921 [MyQrtzScheduler_QuartzSchedulerThread] DEBUG org.quartz.impl.jdbcjobstore.StdRowLockSemaphore - Lock 'TRIGGER_ACCESS' given to: MyQrtzScheduler_QuartzSchedulerThread
    2015-01-29 13:01:05,954 [MyQrtzScheduler_QuartzSchedulerThread] DEBUG org.quartz.impl.jdbcjobstore.StdRowLockSemaphore - Lock 'TRIGGER_ACCESS' returned by: MyQrtzScheduler_QuartzSchedulerThread
    2015-01-29 13:01:05,955 [MyQrtzScheduler_QuartzSchedulerThread] DEBUG org.quartz.simpl.PropertySettingJobFactory - Producing instance of Job 'node1_1422543657050.Job2', class=com.mycompany.myapp.jobs.Job2
    2015-01-29 13:01:05,961 [MyQrtzScheduler_Worker-1]  INFO org.quartz.plugins.history.LoggingTriggerHistoryPlugin - Trigger node1_1422543657050.Job2Trigger fired job node1_1422543657050.Job2 at:  13:01:05 01/29/2015
    2015-01-29 13:01:05,962 [MyQrtzScheduler_Worker-1]  INFO org.quartz.plugins.history.LoggingJobHistoryPlugin - Job node1_1422543657050.Job2 fired (by trigger node1_1422543657050.Job2Trigger) at:  13:01:05 01/29/2015
    2015-01-29 13:01:05,963 [MyQrtzScheduler_Worker-1] DEBUG org.quartz.core.JobRunShell - Calling execute on job node1_1422543657050.Job2
    2015-01-29 13:01:05,963 [MyQrtzScheduler_Worker-1]  WARN com.mycompany.myapp.jobs.Job2 - No outbound files found; Outbound File SLA Job cannot check for SLA breaches.
    2015-01-29 13:01:05,965 [MyQrtzScheduler_Worker-1]  INFO org.quartz.plugins.history.LoggingJobHistoryPlugin - Job node1_1422543657050.Job2 execution complete at  13:01:05 01/29/2015 and reports: null
    2015-01-29 13:01:05,966 [MyQrtzScheduler_Worker-1]  INFO org.quartz.plugins.history.LoggingTriggerHistoryPlugin - Trigger node1_1422543657050.Job2Trigger completed firing job node1_1422543657050.Job2 at  13:01:05 01/29/2015 with resulting trigger instruction code: DO NOTHING

OP給出了以下答案。

問題是,我正在使用具有唯一組ID(調度程序ID)而不是集群中所有主機共有的組ID的身份定義石英作業。 由於調度程序ID對主機而言是唯一的,因此群集中的每個主機都將使用完全限定的作業名稱groupId.jobName來查看該作業是否已經存在,並且可以肯定地發現它不存在,因此它將創建一個新的實例。啟動期間的Job1和Job2。 沒有Java中的顯式請求或Oracle中的手動sql語句,石英作業/觸發器永遠不會過期或清除。 因此,隨着時間的流逝,實例將建立起來,而不是用石英運行Job1和Job2的單個實例,而是運行隨時間推移創建的每個作業的所有實例(因此將執行多個執行和多個電子郵件警報)。

解決方案是,在定義作業的身份時,我用諸如“ MyQuartzJobs”之類的靜態字符串替換schedulerId。

基本上,我更改了以下Java代碼行:

JobDetail job = 
newJob(Job1.class).withIdentity(JOB1_JOB_NAME,  uniqueSchedulerId)
.withDescription(JOB1_DESC + " created [" + new Date() + "]")
.storeDurably(false)
.requestRecovery(false)
.build();

如下所示:

JobDetail job = 
newJob(Job1.class).withIdentity(JOB1_JOB_NAME,  "MyQuartzJobs")
.withDescription(JOB1_DESC + " created [" + new Date() + "]")
.storeDurably(false)
.requestRecovery(false)
.build();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM