Zookeeper客户端会话创建过程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/asty9000/article/details/85494529

初始化阶段

1.初始化ZooKeeper对象。通过调用ZooKeeper的构造方法来实例化一个ZooKeeper对象,在初始化过程中,会创建一个客户端的Watcher管理器:ClientWatchManager。

2.设置会话默认Watcher。如果在构造方法中传入了一个Watcher对象,那么客户端会将这个对象作为默认Watcher保存在ClientWatchManager中。

3.构造ZooKeeper服务器地址列表管理器:HostProvider。对于构造方法中传入的服务器地址,客户端会将其存放在服务器地址列表管理器HostProvider中。

4.创建并初始化客户端网络连接器:ClientCnxn。Zookeeper客户端首先会创建一个网络连接器ClientCnxn,用来管理客户端与服务器的网络交互。在创建ClientCnxn的同时,还会初始化客户端两个核心队列outgoingQueue和pendingQueue,分别作为客户端的请求发送队列和服务端响应的等待队列。ClientCnxn连接器的底层I/O处理器是ClientCnxnSocket,因此此时还会创建ClientCnxnSocket处理器。

5.初始化SendThread和EventThread。客户端会创建两个核心网络线程SendThread和EventThread,SendThread用于管理客户端和服务端之间的所有网络I/O,EventThread用于进行客户端的事件处理。同时客户端还会将ClientCnxnSocket分配给SendThread作为底层网络I/O处理器,并初始化EventThread的待处理事件队列waitingEvents,用于存放所有等待被客户端处理的事件。

会话创建阶段

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

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

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

9.构造ConnectRequest。SendThread会负责根据当前客户端的实际配置,构造一个ConnectRequest请求,该请求代表了客户端试图与服务器创建一个会话。同时,ZooKeeper客户端还会进一步将该请求包装成网络I/O层的packet对象,放入请求发送队列outgoingQueue中去。

10.发送请求。当客户端请求准备完毕后,就可以向服务器发送请求了。ClientCnxnSocket负责从outgoingQueue中取出一个待发送的Packet对象,将其序列化成ByteBuffer后,向服务端进行发送。

响应处理阶段

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

12.处理Response。ClientCnxnSocket会对接收到的服务端响应进行反序列化,得到ConnectResponse对象,并从中取出ZooKeeper服务端分配的SessionId。

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

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

15.查询Watcher。EventThread线程收到事件后,会从ClientWatchManager管理器中查询出对应的Watcher,针对SyncConnected-None事件,直接找出步骤2中存储的默认Watcher,然后将其放到EventThread的waitingEvents队列中去。

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

猜你喜欢

转载自blog.csdn.net/asty9000/article/details/85494529