Zookeeper客户端

一,Zookeeper客户端的主要组件


Zookeeper客户端主要由以下几个核心部分组成:

1,Zookeeper实例:客户端入口。

通过调用Zookeeper构造方法生成客户端实例。

2,ClientWatchManager:客户端Watcher管理器。

3,HostProvider:客户端地址列表管理器。

4,ClientCnxn:客户端核心线程。内部又包含2个线程,SendThread和EventThread。SendThread是一个IO线程,主要负责Zookeeper客户端与服务端的网络通信。EventThread是一个事件线程,主要负责对服务端事件进行处理。


二,Zookeeper客户端的启动流程


首先看一下Zookeeper构造方法

Zookeeper(String connectString, int sessionTimeout, Watcher watcher, boolean canBeReadOnly)


初始化阶段


1,设置默认Watcher。

如果在Zookeeper的构造方法中传入一个Watcher对象的话,Zookeeper会将这个对象保存在ZKWatcherManager的defaultWatcher中,作为整个客户端会话期间的默认watcher。

2,设置Zookeeper服务器地址列表。

对于传入的服务器地址,客户端会将其保存在服务器地址列表管理器HostProvider中。

3,创建ClientCnxn。

Zookeeper客户端首先会创建一个网络连接器ClientCnxn,用来管理客户端与服务端的网络通信。

4,初始化SendThread和EventThread。

SendThread是一个IO线程,主要负责Zookeeper客户端与服务端的网络通信。EventThread是一个事件线程,主要负责对服务端事件进行处理。


会话创建阶段


5,启动SendThread和EventThread。

SendThread首先会判断当前客户端的状态,进行一系列清理工作,为客户端发送会话创建请求做准备。

6,获取一个服务器地址。

在开始创建TCP连接之前,SendThread首先需要获取一个Zookeeper服务器的地址,这通常是从HostProvider中随机获取一个地址,然后委托给ClientCnxnSocket去创建与Zookeeper服务端的TCP连接。

7,创建TCP连接。

获取到服务器地址后,ClientCnxnSocket负责和服务端创建一个TCP长连接。

8,构造ConnectRequest请求。

SendThread根据当前客户端的实际设置,构造一个ConnectRequest请求,该请求代表了客户端试图与服务端创建一个会话。同时,Zookeeper客户端还会进一步将该请求包装成网络IO层的Packet对象,放入请求发送队列outgoingQueue中。

9,发送请求。

ClientCnxnSocket从outgoingQueue取出一个待发送的Packet对象,将其序列化成ByteBuffer后,向服务端进行发送。


响应处理阶段


10,接收服务端响应

ClientCnxnSocket接收到服务端的响应后,会先判断当前的客户端状态是否是已初始化状态。如果尚未完成初始化,那么就认为该响应一定是会话创建请求的响应,直接交给readConnectResult方法来处理该响应。

11,处理response

ClientCnxnSocket会对接收到的服务端响应进行反序列化,得到ConnectResponse对象,并从中获取到Zookeeper服务端分配的会话sessionId。

12,连接成功。

连接成功后,一方面需要通知SendThread线程,进一步对客户端进行会话参数的设置,包括readTimeout和connectTimeout等,并更新客户端状态。另一方面,需要通知地址管理器HostProvider当前成功连接的服务器地址。

13,生成事件,SyncConnected-None。

为了能够让上层应用感知到会话的成功创建,SendThread会生成一个事件SyncConnected-None,代表客户端与服务端创建会话成功。并将该事件传递给EventThread。

14,查询watcher

EventThread收到事件后,会从ClientWatchManager管理器查询出对应的watcher,针对SyncConnected-None事件,找出步骤2中存储的默认的watcher,然后放到EventThread的waitingEvents队列中。

15,处理事件。

EventThread不断从waitingEvents队列中取出待处理的watcher,然后直接调用该对象的process接口方法,以达到触发watcher的目的。

你可能感兴趣的:(Zookeeper客户端)