Java Search

Monday, December 04, 2006

Using Quartz Scheduler in a cluster

In a previous post, I described how to use Quartz scheduler for scheduling. In this post, I describe the configuration changes required for using Quartz Scheduler with Scheduling. Clustering currently only works with the JDBC-Jobstore (JobStoreTX
or JobStoreCMT). Features include load-balancing and job fail-over (if the JobDetail's "request recovery" flag is set to true). It is important to note that
  • When using clustering on separate machines, make sure that their clocks are synchronized using some form of time-sync service (clocks must be within a second of each other). See http://www.boulder.nist.gov/timefreq/service/its.htm.
  • Never fire-up a non-clustered instance against the same set of tables that any other instance is running against.
  • Each instance in the cluster should use the same copy of the quartz.properties file.
The following is an example of how to setup clustering. I implemented it as a stand-alone application. The same settings can be used in clusetered environment.
  1. Copy the source code from the example from the quartz example and add the follwing line to the QuartzTest.java class
    jobDetail.setRequestsRecovery(true);
    before adding jobDetail to the trigger. This is job failover.
  2. You have to add the following to the quartz.properties file:
    org.quartz.jobStore.isClustered = true
    org.quartz.jobStore.clusterCheckinInterval = 20000
    This sets up quartz for clustering
  3. Each server must have the same copy of the configuration file.
    org.quartz.scheduler.instanceId = AUTO
    To auto-generate instance ids.
  4. Create the data tables by using the sql scripts provided with the quartz download. The scripts are in the quartz\docs\dbTables directory.
When running the example, you can see the changes in DB in the SIMPLE_TRIGGERS and FIRED_TRIGGERS tables. The following is the quartz.properties file that I used. It has to be in the classpath.
#============================================================================
# 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:@localhost:1521:orcl
org.quartz.dataSource.myDS.user = scott
org.quartz.dataSource.myDS.password = tiger
org.quartz.dataSource.myDS.maxConnections = 5
org.quartz.dataSource.myDS.validationQuery=select 0 from dual
In order to use the datasources from your application server, change the datasource definition to the following
org.quartz.dataSource.myDS.jndiURL=jdbc/myDataSource
org.quartz.dataSource.myDS.java.naming.factory.initial=com.evermind.server.rmi.RMIInitialContextFactory
org.quartz.dataSource.myDS.java.naming.provider.url=ormi://localhost
org.quartz.dataSource.myDS.java.naming.security.principal=admin
org.quartz.dataSource.myDS.java.naming.security.credentials=123

16 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. This article is great. How do I accomplish the same within a Spring application?

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. hi,

    You have mentioned "load balance" feature of Quartz in a cluster. How do you configure load balancing in Quartz?

    Thanks

    ReplyDelete
  5. I recommend that the max number of connections be either equal to or higher than the threadCount particularly if you have jobs that will interact with a database.

    courtesy of
    akamai technology solutions inc

    ReplyDelete
  6. I running quartz in a cluster with two boxes. In one of them i getting the next message: "This scheduler instance (SchedulerName) is still active but was recovered by another instance in the cluster. This may cause inconsistent behavior".
    After that my jobs start to be executed just in one instance of the cluster.

    I'm using quartz 1.6 and configuration showed in this site. Any suggestion?

    ReplyDelete
  7. Hi Abhi!!

    Does Quartz support Application Server clustering (not DB clustering)? My application is running in an Application Server clustering environment. I can see from the server console saying 'INFO: Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED started.' What can be done if we need to run jobs in App server clustering environment?

    Thanks,
    Jithesh

    ReplyDelete
  8. Hi Jithesh,
    We are in same positions. The cluster is built with several JBoss nodes. I made Quartz running as a HA singleton on the master node, so it'a running at only 1 place. Think of something similar ;)

    Regards
    HiFi

    ReplyDelete
  9. Hi,

    Iam facing an issue with quartz schedulers, details below,

    We are using Quartz along with OSWorkflow and WebWork in our J2EE application with Oracle DB support.

    The jobs are storing into the Oracle DB(tables starts with QRTZ_ ) when a action performed in application, for the particular time(Start time and next fire time) the job is not strarting to trigger, the records stay in DB as inserted.

    It is happening for our production environment, hence not able to debug much on this issue.

    In logs I could not find any exceptions about this triggers. I hope the triggers is failing to attempt/start the scheduler.

    Please provide your suggestion on this why the triggers failed to execute for the specified time frame.

    Thanks,
    -Jee

    ReplyDelete
  10. Thanks Abhi. Nice article.
    I followed the steps and came accross this error:
    10:56:07,562 ERROR [STDERR] org.quartz.JobPersistenceException: Couldn't store job: ORA-01002: fetch out of sequence
    [See nested exception: java.sql.SQLException: ORA-01002: fetch out of sequence

    I configured the same quartz properties in the spring bean org.springframework.scheduling.quartz.SchedulerFactoryBean. I could not post theXML as it is not allowed here.

    Any ideas to overcome this????

    ReplyDelete
  11. Hi Abhi,
    Can you please send the sample code to my gmail. It will be helpful for me.

    ReplyDelete
  12. Hi,
    i using Quartz with Jboss AS7 cluster. On the properties i have set properties as given in your blog above. Problem is i still see the quartz thread getting invoked only on the HA master node.
    What i need to do make sure that the job execution is clustered?

    Regards
    Rajeev

    ReplyDelete
  13. Hi,
    I too have same issue with Job execution is clustered using weblogic server. How can i implement to run jobs in App server clustering environment?

    ReplyDelete
  14. Hi,

    I am using quartz in cluster env. in local i am using h2 DB and application is running fine in local but in server we are using Oracle DB. At server my application is throwing exception : Registration of jobs and triggers failed: oracle/sql/BLOB?

    Can you give me any pointer regarding the same?
    Thanks

    ReplyDelete
  15. It's interesting that many of the bloggers to helped clarify a few things for me as well as giving.Most of ideas can be nice content.The people to give them a good shake to get your point and across the command.
    Java Training in Chennai

    ReplyDelete

Popular Posts