前面我们看了watcher的基本概念以及zookeeper的一些使用场景,那它是如何做到的;
下面我们说下它的监听或者说是接收通知是如何做到的,首先我们要理解下官方给zookeeper这个类的解释,
首先该类的方法是线程安全的。
一旦与服务器建立连接,就会为客户端分配一个会话ID。客户端会定期向服务器发送心跳以保持会话有效。如果客户端长时间未能向服务器发送心跳,服务将过期会话。
如果客户端当前连接的ZooKeeper服务器失败或没有响应,客户端将在其会话ID过期之前自动尝试连接到另一台服务器。成功则客户端可以继续使用客户端。
ZooKeeper的方法要么同步,要么异步。在服务器响应之前,同步方法会阻塞。异步方法只是将请求排队等待发送即返回。它们采用同一个回调对象并返回(rc),
一些成功的调用方法可以在ZooKeeper服务器的“数据节点”上留下watch。其他成功的调用可以触发这些watch。一旦watch被触发,事件将被传递给watch的客户端。每个watch只能触发一次。
我们按照之前分布式锁的代码逻辑顺序先看它的getChildren方法, 它会返回给定路径的节点的子节点列表。如果watch为true并且调用成功(没有抛出异常),则会在给定路径的节点上留下一个watch,具体做法是当你把watch设为true,它会为特定路径注册一个观察者, 给该观察者赋子节点监听注册器,
这里的请求头类型是8,create的话是1,(其他一些值在ZooDefs.OpCode接口里),然后通过cnxn.submitRequest(h, request, response, wcb);提交请求,进去我们可以发现它会被封装在queuePacket对象里,然后存入LinkedBlockingDeque
官方给该同步代码块解释是:这里的同步块有两个目的:1. 与 SendThread.run() 中的最终 cleanup() 同步以避免竞争 2. 针对每个数据包同步。因此,如果添加了 closeSession 数据包,则会通知稍后的数据包;
对于这个state可是让我又学到一个名词,守护线程;这里它会设置一个守护线程:JVM 退出时,线程能够自动关闭;
我们顺着sendThread搜索会找到sendPacket方法,继续找会发现createBB方法;
它就序列化了一下,百度了一下序列化定义:序列化是将对象状态转换为可保持或可传输的形式的过程。序列化的补集是反序列化,后者将流转换为对象。这两个过程一起保证数据易于存储和传输。
我们继续打开他的ClientCnxnSocketNetty类看createBB下面怎么做的,它会updateLastSend();;
channel.writeAndFlush(writeBuffer)通道写入和刷新
result.addListener(onSendPktDoneListener);这个来进行监听,onSendPktDoneListener干啥的。这里写的是使用单个监听器实例来减少 GC,如果成功,发送计数会进行累加;
我们看完state继续看waitForPacketFinish;
我们看下register的方法;
翻译就是将观察者注册到路径上的一组观察者。参数: rc – 尝试在路径上添加监视的操作的结果代码;后面的下次再说,好长,后面的监听处理分下篇说;好啦!