【问题标题】:Synchronizing a Method Across JVM's跨 JVM 同步方法
【发布时间】:2013-10-23 18:35:31
【问题描述】:

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

【问题讨论】:

  • 2 阶段提交是您需要查看的内容。
  • 最好在数据库字段中使用标志,而不是尝试在应用程序级别解决问题。
  • 因此可能需要一个单线程应用程序来侦听特定端口,并且每个应用程序都会调用此端口而不是调用方法,因此您需要注意整个请求。
  • +1 到数据库。确保它是事务性的(即不是 MyISAM)。
  • 一个数据库,真的,我的意思是 1990 年代。数据库绝对是实现分布式锁的最慢和最差的方法!多么糟糕的建议和懒惰的没有灵感的解决方案。你想要的是distributed lock manager太糟糕了,你不能投票给 cmets!

标签: java concurrency jvm synchronized


【解决方案1】:

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

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

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

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

【讨论】:

  • Apache zookeeper 也值得一看。
猜你喜欢
  • 2023-04-10
  • 1970-01-01
  • 2021-11-09
  • 1970-01-01
  • 2013-02-13
  • 1970-01-01
  • 2016-10-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多