java 应用程序中 class 的单个实例(单例)部署在多个节点中

Single instance(singleton) of a class in a java application deployed in many nodes

在技术讨论中,我遇到了如何跨节点维护单个实例的问题, 然后我回答了以下方法

1) 基于数据库的解决方案

2) 分布式缓存

3) 分片

4)在负载均衡器中维护Singleton单实例

面试官期待更多,因为他回答了 基于 DB 和 Cache 将工作,分片将不起作用,并且没有对负载平衡器方法发表评论,然后他进一步补充说,让我们假设您的应用程序中不允许使用 DB 和 Cache 方法,给我另一个选择 我被困在这一点上。

然后我用谷歌搜索并找到以下内容

How to create singleton java class for multiple jvm support?

Singleton in Cluster environment

https://javaarchitectforum.com/2013/02/19/singleton-design-pattern-with-example/

也找到了应用服务器的一些支持

http://www.onjava.com/pub/a/onjava/2003/08/20/jboss_clustering.html

http://docs.oracle.com/cd/E12840_01/wls/docs103/cluster/service_migration.html#wp1051458

http://docs.oracle.com/cd/E24152_01/Platform.10-1/ATGPlatformProgGuide/html/s1005runningthesameschedulableservice01.html

请帮助我提出你的想法,这将是跨节点实现单个实例(单例)的最佳方法

如果您不知道自己在做什么,所有选项都会失败。我想将单例称为反模式而不是设计模式,因为它经常使用的方式通常是灾难的根源。

现在,让我们来看看答案吧。你应该问面试官:为什么真的需要单例?什么状态真正需要存储在一个特定位置?这个状态是可变的吗?什么是并发策略?主要是写吗?还是主要看书?是否所有访问都必须同步?

您的思考方向错误,因为您认为这个问题确实存在解决方案。好吧,你会找到办法的,但这将是并发性能和绝对同步访问之间的折衷。

现在,让我们快速浏览一下您自己提供的选项:

1) 基于数据库的解决方案

这可行,但您必须确保数据库支持您的锁定策略,并且您要明智地使用它。

2) 分布式缓存

这与基于数据库的解决方案基本相同。您甚至可以编写自己的微服务来完成这项工作。您应该意识到分布式缓存与数据库完全相同,只是针对相同数据的并发读取进行了优化(具有过期策略)。请记住,如果没有很好地解释,缓存解决方案听起来好像您没有意识到缓存通常 invalidates/expires,并且具有即时生成回退。这听起来好像您一直不理解想要拥有一个单例实例的问题 "alive"。

3) 分片

分片是一种技术,如果您的单身人士太大而无法适应前面提到的基于数据库的解决方案,则可以使用这种技术。我非常怀疑你的单身人士会变得这么大。

4) 在负载均衡器中维护Singleton单实例

这会使您的负载平衡器精神分裂,这是个坏主意。负载平衡器是非常简单的组件,应该保持这种状态。

您可能会受益于 http://sw1nn.com/blog/2012/04/11/clojure-stm-what-why-how/ STM,这是 Clojure 中的一项技术,因此应该在 JVM 上工作。此外,我同意 Jan-Willem Gmelig Meyling 上面所说的任何内容。这是您应该避免的反模式。我的 STM 建议特别是在一种不允许你改变状态的语言中,这是这样的事情不会变得危险的前提(它会防止 JWGM 谈论的精神分裂症问题。)