跨 JVM 同步方法

2022-09-03 14:27:03

如何跨 JVM 同步方法?

我的示例是一个 Web 应用程序,它限制用户名多次登录(换句话说,第一个用户可以登录,但如果另一个用户使用相同的用户名登录,他将被拒绝)。

Web 应用程序部署在多个服务器上,因此有多个 JVM,用户可以尝试使用不同的服务器登录,具体取决于负载平衡器。

以下是该方法的外观

public synchronized static SessionData logonSync(String userName, String password) throws Exception 
{
    int count = DB.count("sessions", "WHERE user_name=?", userName);
    if (count > 0)
    {
       throw new Exception("logon.error.loginAlreadyUsed");
    }                   

    return logon(userName, password);
}

由于同步方法,它在1个应用程序服务器上正常工作,但是跨多个JVM?两个用户可能尝试同时登录不同的 Web 应用。我该如何防止这种情况?

* 编辑 *如果您的解决方案想要利用某些事务性缓存方法,则该应用也使用 Memcached。


答案 1

您询问了有关跨 JVM 同步方法的问题。这需要一个处理分布式进程的库。有很多选择,这里只有几个:

  1. Terracotta - 支持将某些字段配置为跨 JVM 的“共享”,因此您可以使用标准的 JVM 锁定,如 sync 关键字,并且它将在多个 JVM 上运行。
  2. JGroups - Jgroups是分布式应用程序的工具包。锁定是它提供的功能之一。这是他们文档中的一个例子

设置分布式锁定从来都不是一件容易的事,无论您使用什么库。如果你需要它,很好,但对于你的例子来说,这似乎有点过分了。其他选项:

  • 在数据库中添加唯一性约束,并让它强制实施唯一性。这可能会对数据库的性能产生影响,因此这实际上取决于您期望获得的流量。
  • 让负载均衡器使用用户名(或其哈希)作为用于将请求分配给 Web 服务器的密钥。这将保证来自相同用户名的请求每次都会到达同一个Web服务器 - 不需要分布式锁,只需使用常规锁即可。

答案 2

推荐