一个工作了8年的粉丝去面试, 在面试过程中被问到单例模式的问题。
他当时还暗自窃喜,因为他已经准备好了7种单例模式的回答。
结果面试官不按套路出牌,问他: 如何设计实现一个集群环境下的分布式单例模式?
顿时傻眼了。
问题解析
单例模式,相信每个人都会。
但是分布式集群环境下的单例模式,就很困难了。
但大家也不用急,其实这个问题应该拆解成两个部分。
-
如何实现跨进程级别的单例实例
-
如何保障在任何时刻下只有一个进程可以访问这个实例
关于第一个点,如果按照常规单例模式的思路去思考,是无法实现的,
因为不管怎么做,最终每个进程获取到的对象实例
在进程内的内存地址都是不一样的。
所以,我们应该换一个思路,也就是对象状态的唯一性,简单来说。
就是不同进程在获取这个对象实例的时候,都能保持上一个进程对这个对象修改后的状态。
基于这个思路,我们来看一下回答。
问题答案
首先,可以把单例对象序列保存到文件里面,然后再把这个文件存储到外部的共享存储组件中。
其次,各个进程在使用这个单例对象的时候,先从外部共享存储中读取到内存,并且反序列化成对象来使用。
最后,使用完成以后,再把这个对象序列化以后存储回外部共享存储组件中,并显示的把这个对象从本地内存中删除。
基于这样的操作,就能保证各个进程对单例对象的状态一致性。
但是,因为多个进程可以同时访问这个单例对象,所以为了保证在任何时候只有一个进程访问单例对象。
就需要引入分布式锁的设计,也就是一个进程在获取到分布式锁以后,才能访问共享单例对象,使用完以后在释放分布式锁。
分布式锁的实现,可以使用zookeeper、Etcd、Redis等,以上就是我的理解。
总结
大家知道怎么回答了吗?
如果你喜欢我的作品,记得点赞收藏加关注哦!!!
另外,我将所有Java面试系列制作成了完整的面试文档。它的便捷之处在于,可以通过检索的方式,找到你想要的面试题,目前已经更新350期,总计超过35W字!