26
votes

I have a layer of identical app servers behind a load balancer. For operational reasons I have the constraint that the application configuration on both app servers must be identical so that nodes can easily be added and removed. All app servers share the same database. App servers are not/will not be clustered.

This has worked fine until now, but now I would like to have a scheduled job that executes on exactly one of the app servers. All app servers will run Quartz and have the same schedule for running jobs. The trigger will fire on every app server, but I would like only one app server to actually execute the job - essentially they all race to start and only one actually starts, the remaining app servers just ignore the job. The idea here is that if we lose an app server, another one would run the job instead, and if we add new app servers, they will take their turn at running jobs.

I was planning to do this by having a 'job lock' table in the database that all app servers would read prior to starting a job and only start if job is 'unlocked'. The app server that makes the update first to the table will essentially block others by updating the table to a running state/resetting it at the end of the job.

Before I build this, I'd appreciate some input from those with more experience of Quartz:

a) Can I hook this behaviour into Quartz so that it doesn't have to be done on a per job basis? I.e. developers can add new jobs without worrying about job locking as it is abstracted away.

b) Does Quartz provide any built in mechanisms to achieve something similar to above so I don't have to roll it myself?

Thanks!

1

1 Answers

28
votes

Do you think this will work for you? http://www.quartz-scheduler.org/documentation/quartz-2.3.0/configuration/ConfigJDBCJobStoreClustering.html Excerpt from the link

Clustering currently only works with the JDBC-Jobstore (JobStoreTX or JobStoreCMT), and essentially works by having each node of the cluster share the same database.

Load-balancing occurs automatically, with each node of the cluster firing jobs as quickly as it can. When a trigger's firing time occurs, the first node to acquire it (by placing a lock on it) is the node that will fire it.`