其他
阿里巴巴为什么不用 ZooKeeper 做服务发现?
1,《往期精选优秀博文都在这里了!》 2、他来了!IDEA 2020.1 新版介绍!不过升级前请注意避坑! 3、七个略火的Spring Boot+Vue开源项目! 4、十个你可能不曾用过的Linux命令!巨好用! 5、分库分表 PK NewSQL数据库!
数据一致性需求分析
Si = F(service-name)
,以 service-name
为查询参数,service-name
对应的服务的可用的 endpoints (ip:port)
列表为返回值.注: 后文将 service 简写为 svc。
endpoints (ip:port)
不一致性带来的影响,即 CAP 中的 C 不满足带来的后果 :分区容忍及可用性需求分析
难以掌握的 Client/Session 状态机
难以承受的异常处理
如果说要选出应用开发者在使用 ZooKeeper 的过程中,最需要了解清楚的事情?那么根据我们之前的支持经验,一定是异常处理。 当所有一切(宿主机,磁盘,网络等等)都很幸运的正常工作的时候,应用与 ZooKeeper 可能也会运行的很好,但不幸的是,我们整天会面对各种意外,而且这遵循墨菲定律,意料之外的坏事情总是在你最担心的时候发生。 所以务必仔细了解 ZooKeeper 在一些场景下会出现的异常和错误,确保您正确的理解了这些异常和错误,以及知道您的应用如何正确的处理这些情况。
ConnectionLossException 和 Disconnected 事件
简单来说,这是个可以在同一个 ZooKeeper Session 恢复的异常 (Recoverable), 但是应用开发者需要负责将应用恢复到正确的状态。 发生这个异常的原因有很多,例如应用机器与 ZooKeeper 节点之间网络闪断,ZooKeeper 节点宕机,服务端 Full GC 时间超长,甚至你的应用进程 Hang 死,应用进程 Full GC 时间超长之后恢复都有可能。 要理解这个异常,需要了解分布式应用中的一个典型的问题,如下图: 在一个典型的客户端请求、服务端响应中,当它们之间的长连接闪断的时候,客户端感知到这个闪断事件的时候,会处在一个比较尴尬的境地,那就是无法确定该事件发生时附近的那个请求到底处在什么状态,Server 端到底收到这个请求了么?已经处理了么?因为无法确定这一点,所以当客户端重新连接上 Server 之后,这个请求是否应该重试(Retry)就也要打一个问号。 所以在处理连接断开事件中,应用开发者必须清楚处于闪断附近的那个请求是什么(这常常难以判断),该请求是否是幂等的,对于业务请求在 Server 端服务处理上对于"仅处理一次" "最多处理一次" "最少处理一次"语义要有选择和预期。 举个例子,如果应用在收到 ConnectionLossException 时,之前的请求是 Create 操作,那么应用的 catch 到这个异常,应用一个可能的恢复逻辑就是,判断之前请求创建的节点的是否已经存在了,如果存在就不要再创建了,否则就创建。 再比如,如果应用使用了 exists Watch 去监听一个不存在的节点的创建的事件,那么在 ConnectionLossException 的期间,有可能遇到的情况是,在这个闪断期间,其它的客户端进程可能已经创建了节点,并且又已经删除了,那么对于当前应用来说,就 miss 了一次关心的节点的创建事件,这种 miss 对应用的影响是什么?是可以忍受的还是不可接受?需要应用开发者自己根据业务语义去评估和处理。
SessionExpiredException 和 SessionExpired 事件
Session 超时是一个不可恢复的异常,这是指应用 Catch 到这个异常的时候,应用不可能在同一个 Session 中恢复应用状态,必须要重新建立新 Session,老 Session 关联的临时节点也可能已经失效,拥有的锁可能已经失效。... 我们阿里巴巴的小伙伴在自行尝试使用 ZooKeeper 做服务发现的过程中,曾经在我们的内网技术论坛上总结过一篇自己踩坑的经验分享 在该文中中肯的提到: ... 在编码过程中发现很多可能存在的陷阱,毛估估,第一次使用 zk 来实现集群管理的人应该有 80% 以上会掉坑,有些坑比较隐蔽,在网络问题或者异常的场景时才会出现,可能很长一段时间才会暴露出来 ...