【问题标题】:Java locking on muliple servers多台服务器上的 Java 锁定
【发布时间】:2013-02-18 23:56:16
【问题描述】:

我几乎没有可以由用户保留的座位。一次,只有一个用户可以参与预订过程,因此同一座位不会被多个用户预订。在我的 Java 代码中,我使用了“同步”关键字来完成它。这行得通。

但是,现在我的代码部署在两台服务器上,比如 S1 和 S2。假设,假设有最后一个座位可用。两个用户,比如 U1 和 U2,想要保留最后一个座位。负载均衡器可能会将用户 U1 发送到服务器 S1 并将用户 U2 发送到服务器 S2。现在,“本地”同步仍然可以以相同的方式工作,但它不能在预订时阻止其他用户。这会使两个用户都保留最后一个座位,这是个问题。

那么问题是如何确保多个用户在多服务器环境中保留席位而不会发生任何冲突?

【问题讨论】:

  • 您在使用 javaEE 和企业 javabeans 吗?
  • Java 语言或库不提供多平台同步。您可以尝试为此配置 S1 和 S2 使用的共享数据库,但这在 Java 之外。
  • 是的,我使用的是 JavaEE,但不是企业级 Javabeans。

标签: java locking synchronized


【解决方案1】:

在语言层面上很难做到。一些分布式缓存可能会有所帮助,例如 Terracotta 确实可以处理集群环境中的同步关键字,但我还没有尝试过,而且肯定会造成性能损失。我会非常小心地让实例等待一些重要的时间,就像你的情况一样。

否则,分布式 JNDI、分布式单例或类似的东西可以使服务器实例进行通信并在此过程中检查是否有帮助。

但在实践中,通常通过乐观锁定来避免这个问题。您可能会简单地假设这仅在某些不寻常/不太可能的时刻发生,并像在一个实例中那样做事。并找出一种方法,当它没有时该怎么做。 这变得更像是业务逻辑场景,最好的方法就是找到一种让用户最不可能不满意的方法。

通常在持久性/数据库级别保证一致性,因此您可以将其写下来。我当然不会使用 synchronized 关键字来阻止可能保持几分钟或更长时间的实例,因为这会导致内存泄漏或任何其他资源耗尽。

我个人喜欢在使用处理此问题的 JPA/Hibernate 时使用 L2 缓存。当 OpenJPA 只通知其他实例实体已更改并且他们应该从其 L1 缓存中撤消它时,它有一种性能友好的方式来处理 L2 的事情。在您的情况下,这可能是比使用同步 Java 语言关键字“同步”更好的方法。

考虑如何处理它是一种很好的态度,因为根据我的经验,它在许多应用程序中都被忽略了。它往往成为一种低概率的情况,业务导向的经理很难理解为什么应该投资它。但它有能力在生产中出现问题时产生严重的反弹。

【讨论】:

  • 感谢玛丽安的帮助。您能否详细说明分布式 JNDI?我想,那将是我感兴趣的。
  • 这取决于平台,我知道在 Weblogic 中,您可能会使用配置让不同的实例相互了解。
  • 我用谷歌搜索了一下,Apache Zookeper 可能会在集群环境中为您提供类似的东西。
  • 再次感谢玛丽安。我会探索它,看看它是否能解决我的问题。
【解决方案2】:

分布式系统的通信方式基本上有四种:

  1. 共享数据库。
  2. 远程过程调用
  3. 消息传递。
  4. 共享文件系统。

考虑共享数据库方法。 .如果您不需要大规模扩展,最简单的方法是使用关系数据库,因为它们几乎都提供了一定程度的 ACID(原子性、一致性、隔离性和持久性)。 . .

您可以设置事务,并在发生冲突时回滚/处理 - 这称为乐观锁定策略。

如果你使用 Spring + JPA/Hibernate,所有的辛苦工作都已经为你完成了,你只需要在你的更新方法中添加一个 @Transactional 注释。 . .一本关于 Spring 的好书是《Spring in Action》。

另一种选择是使用分布式缓存。

【讨论】:

  • 感谢贾斯珀的帮助。我正在使用 Spring+Hibernate。我的数据库模式的定义方式是我有一个 REGISTRATION 和 EVENT 表。我从 EVENT 表 (A) 中获取可用席位总数,然后从 REGISTRATION 表中获取事件的注册总数 (B)。如果 B 小于 A,那么我在注册表中插入一条新记录并完成用户注册。所以基本上,座位是否已满是在代码中决定的。所以我不确定在这里放置 @Transactional 注释是否会有所帮助。让我知道你的看法。
  • 除非它会影响性能,否则请尝试利用您的数据库。这将是最简单的。在分布式环境中,您仍然需要一些事实。 . .
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多