强烈推荐一个大神的人工智能的教程:http://www.captainai.net/zhanghan
zk在dubbo中是服务注册与发现的注册中心,dubbo的调用过程是consumer和provider在启动的时候就和注册中心建立一个socket长连接。provider将自己的服务注册到注册中心上,注册中心将可用的提供者列表notify给consumer,consumer会将列表存储到本地缓存,consumer选举出一个要调用的提供者,去远程调用。 ![这里写图片描述](https://img-blog.csdn.net/20180618111558511?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poMTU3MzI2MjE2Nzk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70) 如果这时候使用的是单点的zk,当zk宕机了,会发生什么呢?zk宕机后不会影响现有consumer和provider之间的调用,但是新的provider想要注册到注册中心上是不行的,因为zk已经宕机了。因此单点zk一旦宕机就会影响新的提供者的注册,和新的消费者去订阅可用列表。 因此我们需要将zk搭建成集群的,那么问题又来了,搭建集群时搭建几台呢?建议是搭建奇数台,最少搭建三台,搭建偶数可以吗?是可以的,但是在选举过程中没有太大用处,因为zk的leader也是遵从半数规则,使用公式计算半数(zk服务器的总数/2+1),3的半数是2,4的半数是3,因此3台和4台允许宕机的机器数都是1台。 搭建好了zk集群后,问题又出现了,数据的一致性如何保证呢?先来看一下zk的数据结构,是类似于树形结构的,我们可以看到在com.foo.BarService这个接口下的providers下可以有多个节点,也即多个提供者,假设BarService这个接口对应的提供者有两个,这时有两个客户端同时请求这个接口,一个客户端请求提供者1,另一个客户端请求提供者2,同时执行的业务逻辑是将a的值加1,他们请求到的a的值都是0,这时,最终的结果是什么呢?在分布式情况下保证数据一致性是一个必须思考的问题,解决办法有很多,例如,分布式锁,版本控制等。 ![这里写图片描述](https://img-blog.csdn.net/20180618114821680?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poMTU3MzI2MjE2Nzk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70) zk有自己的机制,在集群的情况下,zk会选举出一个leader负责写操作,剩下的都可以负载读操作,这样就可以将读写分离,保证的单一性,因此就不会出现上述数据不一致的情况了。那么选举的过程是什么呢?请看第二部分,zk的leader选举原理 ![这里写图片描述](https://img-blog.csdn.net/20180618115519114?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poMTU3MzI2MjE2Nzk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)