14

如何跨 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。

4

1 回答 1

16

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

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

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

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