Reputation: 63
I'm scheduling background task to run in fixed-intervals, but as tomcat is running in multiple instances (i.e. multiple start Apache servers; 3 in my case), then the task runs 3 times in each interval.. I would like it to run once (no matter the number of Tomcat instances running).
I'm running a servlet loaded on startup (in web.xml) which will initiate my task:
<servlet>
<servlet-name>OnInit</servlet-name>
<servlet-class>box.OnInit</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
OnInit class initiate single instance of that class:
public class BGTaskRefresh {
private static BGTaskRefresh refreshTaskFactory = null;
private final Timer timer = new Timer();
public BGTaskRefresh() {}
public static void init()
{
if( refreshTaskFactory == null )
{
refreshTaskFactory = new BGTaskRefresh();
refreshTaskFactory.start();
}
}
public void start()
{
timer.schedule(
new TimerTask()
{
public void run()
{
boxService box = new boxService();
box.refreshMethod();
}
},
5 * 60 * 1000, // 5-Min Delay for first run
60 * 60 * 1000); // 60-Mins (Interval between 2 runs)
}
}
Upvotes: 3
Views: 1047
Reputation: 340723
You might want to have a look at quartz-scheduler, especially its clustering capabilities:
(source: quartz-scheduler.org)
This might be an overkill in your situation, but Quartz will take care of running the job on only a single instance (using database for synchronization) and will automatically run the job on an idle server.
Another option is hazelcast and distributed locks and queues it provides.
Upvotes: 3
Reputation: 4112
You will need some sort of synchronization mechanism. Although ideally you'd want a distributed scheduler (e.g. Quartz cluster), considering your usage scenario you're likely to have either some mechanism for shared session state or a shared database underlying your application; you can simply record the operation and grab a database-based lock to ensure only one instance will run the command at a time (and double-check after the lock grab to ensure you're not running the same task twice).
Here's one article I've found with a technique for DB-based locking: http://blog.udby.com/archives/15
Upvotes: 0