Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create singleton java class for multiple jvm support?

Tags:

java

For example I have DBManager.java Singleton Class, which I have to deploy on clustered environment. It is a web based application, with following deployment stratergy

Apache Load Balancer --> Tomcat 6 (3 Servers in cluster).

I have to maintain single instance of DBManager for 3 tomcat instances.

My code is

package com.db.util;
public class DBManager {
    private static DBManager singleInstance;
    private DBManager () {}
    public static DBManager getSingleInstance() {
        if (singleInstance == null) {
            synchronized (DBManager.class) {
                if (singleInstance == null) {
                    singleInstance = new DBManager ();
                }
            }
        }
        return singleInstance;
    }
}

I have been searching a solution to this problem, and found something like JGroups API. Can this be achieved using JGroups ? Any Idea, How to implement that ?

like image 760
Rahul Agrawal Avatar asked Aug 20 '12 06:08

Rahul Agrawal


1 Answers

Java gives you a singleton in each instance, you need some kind of coordination between the instances so at any given time one of them is active, but if the active one dies then a different instance becomes active.

Some app servers have built in capabilities to control such coordinated worker instances, I don't know whether Tomcat has such a function.

Building such functionality yourself is surprisingly difficult, see this question and note that that question gives links to a useful library - which to me looks quite complex to use.

However in your case you have a database, and that gives you a point of coordination. I haven't designed this in detail, but I reckon it's possible to create a reservation scheme using a dedicated row in a control table. It will be a bit tricky to do this efficiently, balancing the speed of detection of an instance death with the overheads of polling the database to see which instance is active, but it seems doable.

The idea is that the record contains a "reservedUntil" timestamp and "processId". Each process reads the record, if it contains it's own id and the timestamp has not yet expired it knows it can work. When the time is nearly expired, the active process updates the timestamp using an optimistic locking style "Update where timestamp == old timestamp" to manage race conditions. Each non active process waits until the timestamp it last read has expired and then attempts to to take control by updating the record, again using an optimistic locking Update where. Usually that attempt to take control will fail, but if it succeeds we now have a new active instance, and due to optimistic locking we can only ever get one active instance.

like image 199
djna Avatar answered Nov 08 '22 21:11

djna