9

I am using Quartz Scheduler as a Spring bean in a clustered environment.

I have some jobs annotated with @NotConcurrent and they are running once per cluster (i.e. only in one node, only in one thread).

Now I need to run one job on every node of the cluster. I removed the @NotConcurrent annotation, but it only run on every thread on one machine. It does not get fired on other nodes.

What should I annotate the job with?

Example: Job1 NotConcurrent annotated is scheduled at midnight => It fires only on 1 machine every midnight. Job2 annotated scheduled at midnight => It fire on every machine every midnight.

Thank you.

Michaelsoft
  • 777
  • 5
  • 18

1 Answers1

7

AFAIK Quartz job are always executed on a single node that is picked by Quartz. The @NonConcurrent annotation only prevents Quartz from executing the same job concurrently on a particular node.

In other words, you cannot make Quartz execute a job on multiple nodes concurrently. It always picks a single node to execute the job on.

To realize what you describe, you may need multiple jobs (using the same job class and without associated triggers). Then you will need to implement some sort of an orchestrator job that would remotely connect, e.g. via JMX or RMI, to individual nodes and trigger the jobs manually.

You may want to check our product QuartzDesk (www.quartzdesk.com) that provides a web-service that provides a single-endpoint through which you can connect to individual Quartz scheduler instances and, for example, trigger jobs on them.

Jan Moravec
  • 1,808
  • 1
  • 15
  • 18
  • 3
    Thank you. Knowing this limitation led me to use spring @Scheduled annotation with a cron expression to launch that job on all cluster nodes. This hybrid approach is working pretty well. – Michaelsoft May 21 '14 at 19:06
  • Hi Jan, could you please explain a possible solution in more details? I have a similar problem, I need to run a task on all Weblogic nodes (currently there are 2). I'd like to be able to do it ad hoc (e.g. from a servlet). I'm already using quartz for some scheduled jobs, so I was wondering if it's possible to delegate this task distribution to it. Thanks – andreybavt Dec 11 '14 at 22:12
  • The idea was that you implement your worker jobs, but you do not associate any triggers with them. Then you have some sort of an orchestrator job that will be associated with a trigger(s). When Quartz fires the orchestrator job, the job simply connects through JMX, RMI or JAX-WS web-service (if you have QuartzDesk in place) to the Quartz nodes where you want to execute your worker jobs. If you want your worker jobs to execute on all Quartz instances, then the orchestrator job will simply iterate through the list of configured Quartz instances and fire those jobs "manually" over JMX/RMI/JAX-WS. – Jan Moravec Dec 11 '14 at 22:51
  • If you need to ad-hoc execute Quartz jobs, then you can use Quartz API to do that (look for fireJob method). As for the API, it depends on where the Quartz scheduler runs. If it runs in the app your servlet is running in, then you can use the "local" API. If your Quartz scheduler runs in a different app, possibly in a different JVM, then you need to use some remote API. Quartz supports RMI, JMX. I also mentioned JAX-WS that is not provided by Quartz, but it is provided by QuartzDesk that you can use to manage and monitor your Quartz schedulers, jobs, triggers etc. – Jan Moravec Dec 11 '14 at 22:56