Dubbo作为服务框架,一般用的是Zookeeper。
Spring Cloud作为服务框架,一般用的是Eureka。

服务注册发现原理

Eureka

peer-to-peer架构,部署一个集群,但是集群里每个机器的地位是对等的,各个服务可以向任何一个Eureka实例进行服务注册和服务发现,集群里任何一个Eureka实例接收到写请求之后,会自动同步给所有的Eureka实例。
更保证可用性,满足最终一致性。
Eureka是peer模式,可能一个节点再还没同步数据的时候,就已经发生故障死机了,此时其他的服务消费者就还可以从别的机器上拉取注册表,但是可能就获取不到最新的数据了。
image.png

Zookeeper

采用的是一主多从的架构,只有主机器可以进行服务注册,然后同步给其他的从机器。进行服务发现的时候是可以从主/从机器里去读取。
更保证一致性。
Zookeeper是有一个leader节点会接收数据,然后同步写其他节点,一旦leader挂了,就需要重新选举leader,这个过程里为了保护一致性,就牺牲了可用性,不可用一段无时间,但是一个leader选举号了,那么就可以继续写数据,保证一致性。
image.png

一致性保障

CAP定理
C:一致性
A:可用性
P:分区容错性
Eureka 满足 AP, Zookeeper满足CP

服务发现的时效性

Zookeeper的时效性更好,注册或者挂了,一般秒级就能感知到。
Eureka的默认配置非常糟糕,服务发现感知要几十秒,甚至几分钟。上限一个新的服务实例,到其他服务可以发现到,极端情况下要1分钟的时间,然后才能让ribbon去获取每个服务缓存的eureka的注册表进行负载均衡。

在服务发生故障的时候,每隔60秒才去检查心跳,发现这个服务上一次心跳是在60秒之前,隔60秒再去检查心跳,超过90秒后发现还是没有心跳,此时才认为服务挂了, 但这个过程却等待了2分钟。然后后期还要对最新的服务注册列表进行同步至缓存的操作和服务拉取缓存数据的操作,这两个操作也是定时去拉取,可能间隔也是30秒,那这样又得再花费1分钟的时间。最后,整体需要花费三分钟的时间,服务消费者才能知道请求的一个服务提供者的实例挂掉了。

注册中心能承载的服务数量

Zookeeper不适合大规模的服务实例,因为服务上下线的时候,需要瞬间推送数据通知到所有的其他服务实例,所以一旦服务规模太大,到了几千个服务实例的时候,就会导致网络带宽被大量占用。

Eureka,也很难支撑大规模的服务实例,因为每个eureka实例都要接受所有的请求,实例多了压力太大,扛不住,也很难到几千个实例。

解决办法: 多机房、多数据中心、健康检查