I have quartz schedulers load balanced across four cluster. Could you please let me know whether we can do some simple operation so it will be block the quartz schedulers from running in one instance.
All my jobs are JDBC store kind of jobs. My requirement is to disabling jobs from kicking off from instance alone from the cluster.
Any Suggestions?
Related
I have four cron jobs in the application and they work some hours in the day. I deployed them in 6 different instance and I use shedLock to prevent overlapping but it wasn't enough. Because sometimes job delay and lock is removed, then job work 2 times again. How can I configure that if a cron job still working in the one instance, other instances don't start job till this one finish?
why not use distribute executor?if you deployed them in multiple instance,you must manage and schedule the instance's status,for example instance A run at t1,instance B run at t2,it's very complex.You can deployed them on instance or selected distribute schedule executor,in all distribute system, status manage is very difficulty
Try deploying Spring Boot Scheduled Cron jobs one at a time to prevent them being deployed more than one instance
I am moving from single pod(docker image) to multiple pods for my Spring Application on Kubernetes for load handling. But I am facing an issue because I have a cron scheduler method in my application which runs daily at a particular time. If I deploy multiple pods, they all run simultaneously and as a result multiple entries get saved into my DB, but I want only a single pod to execute that function.
I have thought of generating java uuid and saving it in the DB as the function starts execution on each pod. Then in the same function, putting a sleep timer of, let's say, 5 seconds and comparing the uuid from the DB in each pod. The pod which updated the value in the database latest will match that value and will execute the method ahead.
Is this a good approach? If not, please give suggestions that can be done to solve this issue.
You can use a quartz scheduler with JDBC store. This will take care of your requirement automatically.
In short: "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."
Please refer to the official link for details- http://www.quartz-scheduler.org/documentation/quartz-2.3.0/configuration/ConfigJDBCJobStoreClustering.html
Also, you can move the workload to an isolated process, this will be helpful and cleaner, check this out https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/ this will give you an idea.
the better approach is to configure your application to have multiple Spring Profiles and use cron only on one profile. Follow this tutorial https://faun.pub/spring-scheduler-in-multi-node-environment-49814e031e7c
I have configure Quartz JDBCJobStore to run some schedulers on a clustered app and while testing what would happen if one of the servers goes down in the middle of a job processing I found that Quartz does not have a mechanism for the other instances of the app to figure out if one job could not be finished by one of the servers and should be reassign to another one, the problem is that when a server fails it does not have the opportunity to released the lock that it has over the job in the database, so the Job basically stays locked until someone removes the lock by hand.
Is there a built-in feature in Quartz that allow to handle this type of situation (to detect if a job should be release from its lock)?
Requirement is
1. Pick up tasks from database and call web service for those tasks
2. Need to do this in Weblogic cluster where only single instance of scheduler/executor should run.
We have Hazelcast support so i am thinking of getting java ExecutorService from Hazelcast. This ExecutorService will "pick tasks from DB and execute web service call". So each node will have to go through this ExecutorService
Is this the right approach?
My main concern is for not make duplicate calls in the cluster
The reason i do not want to use Quartz scheduler is because i cannot store quartz scheduler in Hazelcast.
Hazelcast didn't support a ScehduledExecutorService. There is an open issue for it here.
I my opinion, you should use a queue : Put tasks on this queue, and on each node poll this queue. You'll be sure to invoke a task only once, and the work will be distributed. This kind of implementation is not fully fault-tolerant, though. If a node crash during the execution of a task, it will be lost.
I have a webapp which will run on 2 different machines. From the webapp it is possible to "order" jobs to be executed at specific times by quartz. quartz is running inside the webapp. Thus quartz is running on each of the two machines.
I am using JDBC datastore to persist the jobs, triggers etc.
However, the idea is that only one of the machines will run jobs and the other will only use quartz to schedule jobs. Thus, the scheduler will only be started (scheduler.start()) on one of the machines.
In the documentation it says
Never run clustering on separate machines, unless their clocks are synchronized using some form of time-sync service (daemon) that runs very regularly (the clocks must be within a second of each other). See http://www.boulder.nist.gov/timefreq/service/its.htm if you are unfamiliar with how to do this.
Never start (scheduler.start()) a non-clustered instance against the same set of database tables that any other instance is running (start()ed) against. You may get serious data corruption, and will definitely experience erratic behavior.
And i'm not sure that the two machines in which my webapp is running have their clocks synchronized.
My question is this: Should i still run quartz in clustering mode for this setup when only one of the quartz instances will be started and run jobs while the other instance will only used for scheduling jobs to be executed by the first instance.
What about simply starting the scheduler on one node only and accessing it remotely on another machine? You can schedule jobs using RMI/JMX. Or you can use a RemoteScheduler adapter.
Basically instead of having two clustered schedulers where one is working and another one is only accessing the shared database you have only a single scheduler (server) and you access it from another machine, scheduling and monitoring jobs via API.
If you will never call the start() method on the second node, then you shouldn't need to worry about clock synchronization.
However you will want to set the isClustered config prop to true to make sure that table-based locking is used when data is inserted/updated/deleted by both nodes.