如何创建支持多jvm的单例java类



例如,我有DBManager.java Singleton类,我必须在集群环境中部署它。这是一个基于web的应用程序,具有以下部署策略

Apache负载均衡器-->Tomcat 6(集群中有3台服务器)。

我必须为3个tomcat实例维护DBManager的单个实例。

我的代码是

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;
    }
}

我一直在寻找这个问题的解决方案,并找到了类似JGroups API的东西。这可以使用JGroups实现吗?有什么想法吗?如何实现?

Java在每个实例中都为您提供了一个单例,您需要在实例之间进行某种协调,以便在任何给定的时间,其中一个实例都是活动的,但如果活动的实例死亡,则另一个实例变为活动的。

有些应用服务器内置了控制这种协同工作实例的功能,我不知道Tomcat是否有这样的功能。

自己构建这样的功能非常困难,看看这个问题,注意这个问题提供了一个有用库的链接——在我看来,使用这个库相当复杂。

然而,在您的案例中,您有一个数据库,这为您提供了一个协调点。我还没有详细设计,但我认为可以使用控制表中的专用行创建预订方案。高效地做到这一点有点棘手,要平衡实例死亡的检测速度和轮询数据库以查看哪个实例处于活动状态的开销,但这似乎是可行的。

其想法是,该记录包含一个"reservedUntil"时间戳和"processId"。每个进程都读取记录,如果它包含自己的id,并且时间戳尚未过期,它就知道它可以工作。当时间即将到期时,活动进程使用乐观锁定样式"Update where timestamp==old timestamp"来更新时间戳,以管理竞争条件。每个非活动进程都会等待,直到它上次读取的时间戳过期,然后尝试通过更新记录来控制,再次使用乐观锁定更新。通常,控制的尝试会失败,但如果成功,我们现在有了一个新的活动实例,由于乐观锁定,我们只能获得一个活动实例。

Singleton确保在给定的JVM中只有一个类实例。

在您的情况下,多个DBManager(每个JVM一个)有什么问题?

最新更新