首页 > 代码库 > Curator源码解析(四)ZooKeeper存在的连接问题
Curator源码解析(四)ZooKeeper存在的连接问题
都说Curator的连接机制比较牛逼,所以在分析Curator的连接和重试机制之前,我想先搞清楚原生的ZooKeeper的连接存在哪些问题。
下面是我查阅资料总结的结果,转载请注明出处: jiq?钦‘s technical Blog
Curator虽然提供所谓的高层抽象API来简化了ZooKeeper的使用,但更重要的是封装了管理到ZooKeeper集群的连接以及重试机制的复杂性,下面我们来详细分析一下Curator在这方面都是怎么做的,不过在这之前先要搞清楚ZooKeeper目前在连接方面有哪些问题。
会话建立
当你new出一个ZooKeeper对象的时候,客户端就建立了与ZooKeeper服务端之间的一个Session(注意这个session是线程安全的,即多个线程可以共用一个ZooKeeper实例),这个Session会有一个超时时限,即失效时间,通过ZooKeeper的构造函数传递进去,客户端会不断发送心跳(多久发送一次和设置的会话超时时限有关)到ZooKeeper服务端,以保持与ZooKeeper服务端的有效连接和Session的有效性。
连接丢失
如果客户端与服务端的网络断开,或客户端连接的ZooKeeper server挂掉,或者与Server的Session的建立后连接还未建立完成,都会出现CONNECTION_LOSS现象,客户端所有watcher都会收到一个disconnected event,客户端连接状态从CONNECTED变为CONNECTING。
自动重连
此时客户端库会自动从ZooKeeper服务器列表中选择一个server来进行重连。
A. 如果重新成功建立与服务端的TCP连接,并且没有超过session的超时时限,那么ZooKeeper客户端将会收到一个SyncConnected event,客户端连接状态就又会变为CONNECTED,连接恢复正常且临时节点和注册的watch事件也不会被删除掉。即使重连在一个很短的时间内完成,也会收到了两个事件。
B. 如果过了很久还是不能重新成功建立与服务端的TCP连接,客户端将会一直保持在disconnected状态,也就永远不会收到Expired event,只会有disconnectedevent(因为事件是来自服务端)。
C. 如果重新成功建立与服务端的TCP连接,但是发现已经超过了session设置的超时时限,那么客户端将会收到一个Expired event,表示会话已经终止SESSION_EXPIRED,此时服务器会将这个客户端注册的所有watcher,以及创建的临时节点全部删除,同时客户端持有的ZooKeeper句柄也会被关闭,唯一能做的就是重建ZooKeeper对象。发生SESSION_EXPIRED的watcher将会看到如下状态转换:
‘connected‘: 会话建立,客户端与ZooKeeper集群正常通信
....client is partitioned from the cluster
‘disconnected‘: 客户端丢失与ZooKeeper集群的连接
....time elapses, 时间逐渐流逝,在‘timeout‘时限后ZooKeeper集群将会终止这个会话,此时处于disconnected状态的客户端将会什么都看不到。
....time elapses, 时间流逝,客户端重新建立与ZooKeeper集群的连接
‘expired‘: 最终客户端重连到ZooKeeper集群,将会收到expiration 通知
连接丢失的处理:
CONNECTION_LOSS意味着客户端和服务器端的TCP连接断开,但是并不意味着请求失败。假如正在执行一个create请求,然后在请求到达服务器以及response返回之前,连接断开,这个create请求就会执行成功,假如在数据包发送到线路之前断开那么create请求就会执行失败。很不幸客户端没办法知道在CONNECTION_LOSS发生后自己的请求是否执行成功,开发人员必须要自己检测是否执行成功,是否需要重试,检测的方法包括检查对应的znode是否存在,或者检测znode节点的值是否已被修改。
会话终止的处理:
SESSION_EXPIRED将会自动关闭ZooKeeper句柄,如果正确操作ZooKeeper集群,会话终止现象很难出现,如果客户端强制关闭一个连接倒是一定会出现这个事件,因为服务器认为客户端已经死掉了。如果真的出现会话失效该如何处理呢?
后面文章将会分析看Curator是否已经解决这些问题:
(1)发出请求时CONNECTION_LOSS的处理,是否能够知道发出的请求已经执行成功,若不成功能够重试。
(2)SESSION_EXPIRED时的处理,能否让临时节点和注册的watch不被删除。
Curator源码解析(四)ZooKeeper存在的连接问题