还是用具体场景来说吧~
比如一个跨行转账的业务;
从银行扣钱的服务在X实例上运行;给银行加钱的服务在Y1、Y2两个实例上运行;
假设,现在一个“从A银行转500块到B银行”的请求进入系统;
然后X实例已经成功处理,即——扣了用户的A银行账户500块钱;
但是,Y1、Y2两个实例突然都挂了,即——没有给用户的B银行账户加500块钱;
这个情况,如果用zookeeper那一套的话,zookeeper会通知X实例,进行回滚;
这样就保证了数据一致性;
那么如果是用Spring Cloud那一套呢?
它是不是用eureka来处理这个问题的?
如果是,eureka是不是也是像zookeeper那样的处理机制(通知回滚)?
如果不是通知回滚,那么eureka又是怎么样的一个机制呢??
有人说Spring Cloud那一套是用“重试”机制来搞的;
那这个“重试”的意思是不是——不停地请求Y1、Y2实例,直到它们恢复正常,然后成功处理加钱的逻辑?然后前端给用户一个提示,比如“24小时之内到账”?
但是如果是这样的话,如果实例一直不恢复正常咋办啊?人工干预吗?
orz,我错了,又TM想太多了~~
原来我举的例子所表征的是一种极限情况,其实像这样的情况还可以无限延伸下去,没完没了了!!!
就算是上升到理论层面:2PC、3PC、Paxos、ZAB这些算法中的任何一种,都不能保证——绝对的——一致性;
只要是在分布式环境中(多个节点通过网络通信的环境中),你总能找到某一种情况,造成数据的不一致!!
所以,答案俩字————无解!!
那么网上那么多人在那里喊得那么大声的各种数据一致性解决方案,又是什么情况噜???
其实那只是默认网络情况不出现较极端异常的情况下,提出的——尽可能保证一致性——的方案。(这样说才对!)
那么,如果强行回到我举的例子中,该怎么办捏?
其实现实环境中是这样的:
根本不是遇到这样的问题时,才去解决!而是尽量通过合理设计,使这样的情况不发生!
也只是“尽量”!!!
但是如果真的发生了呢?!
那时候就该查日志查日志,该赔钱赔钱了尽量把事情嘎平呗~~
不过!
万幸的是,在现代分布式软硬件架构已经有了很多较为成熟的方案的今天!这种情况本身出现的概率也很低了!!
so,很多人都默认不鸟这个问题了....................
so,Spring Cloud那套,其实从根本上讲也是不管这个问题的,
它只是鼓励我们通过合理设计“绕开(使之不发生)”这个问题!
不只是所谓的“重试”这一机制,还有各种方案,反正总之就是通过人为的方案设计去“尽量”解决(绕开)问题而已!
用我举的例子来说,就是——比如不要只搞Y1、Y2两个实例,
可以搞到Y1000甚至更多,1000个实例都挂的概率够低了吧?
(这里我又忍不住想发散一下——那zookeeper那套还搞什么通知回滚,其实也只是另一种的“尽量解决方案”,
因为你回滚也未必不会出现某几个节点通知到了,某几个没通知到的情况,这里不再赘述了);