Zookeeper--客户端架构、会话创建过程

客户端架构

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

  • Zookeeper实例:客户端的入口
  • ClientWatchManager:客户端Watcher管理器
  • HostProvider:客户端地址列表管理器
  • ClientCnxn:客户端核心线程,其内部又包含两个线程,即SendThread和EventThread。前者是一个IO线程,主要负责Zookeeper客户端和服务端之间的网络IO通信;后者是一个事件线程,主要负责对服务端事件进行处理。
    Zookeeper--客户端架构、会话创建过程_第1张图片

会话创建过程

初始化阶段:

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

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

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

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

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

会话创建阶段:

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

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

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

  4. 构造ConnectRequest请求
    在TCP连接创建完毕后,是否就说明已经和ZooKeeper服务器完成连接了呢?其实不然,步骤8只是纯粹地从网络TCP层面完成了客户端与服务端之间的Socket连接,但远未完成ZooKeeper客户端的会话创建。
    SendThread会负责根据当前客户端的实际设置,构造出一个ConnectRequest请求,该请求代表了客户端试图与服务器创建一个会话。同时,ZooKeeper 客户端还会进–步将该请求包装成网络I/O层的Packet对象,放入请求发送队列outgoingQueue中去。

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

相应处理阶段:

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

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

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

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

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

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

你可能感兴趣的:(Zookeeper)