很多服务发现方案采纳zookeeper做为service registry,但是这篇文章提出的观点是,ZK并不适合!
理由主要是以下两点:
- ZK主要的用途是做distributed coordination,所以在CAP的选择上必然是CP(这个有道理,coordination service主要是为了帮助其他别人实现系统一致性的,总不能自身的一致性都无法保证)。然而,对于服务发现来说,更重要的是AP——client发现不正确的server list,总比完全拿不到要好吧。
当然,上述registry不可用的问题,可以通过client caching来缓解。但是,如果new client/server,就无法解决了。
ZK的配置和使用比较复杂,容易导致不可预期的问题。
需要自己写registration/discovery代码。其实,现在已经有apache curator项目提供了实现。
Netflix Eureka是一个专门的服务发现系统,相比ZK主要有如下几点优势:
CAP选择上是AP,即使出现了partition,也能保证register/discover功能可用。当然,新注册的服务只有在同一个partition的client可以发现,client拿到的服务列表也有可能是过期的。这可以通过client端的容错机制来缓解(比如client发现某个服务实例不可连接,可以把它加入黑名单,一段时间内不再尝试)。
如果server因为partition而跟registry断开连接,一般情况下会导致session过期,该server会被移除。但是,实际上server是正常的,某些client可以连上它的。对于这种情况,Eureka有特殊的处理:
if a Eureka server loses connections with too many clients too quickly, it will enter “self-preservation mode” and stop expiring leases. New services can register, but “dead” ones will be kept, just in case a client might still be able to contact them. When the partition mends, Eureka will exit self-preservation mode.
当然,有人提出ZK也支持read-only mode,在partition时也可以提供read操作,但是不支持write。虽然能够提高部分可用性,但是跟Eureka那种完全可用性比还是差一点。