目录
- NIOServerCnxn
- readPayload()
- handleWrite(k)
- process()
NIOServerCnxn
在上一节IOWorkRequest的doWork()方法中提到会将IO就绪的key通过handleIO()
方法提交给NIOServerCnxn处理,一个NIOServerCnxn代表客户端与服务端的一个连接,它用于处理两者之间的交互,先看下其类结构:
从类结构可知,NIOServerCnxn继承了ServerCnxn,实现了Stats和Watcher接口,所以说它本质上也是一个Watcher。再看下它的数据结构:
NIOServerCnxn主要负责客户端与服务端的数据的收发,其中,收到的数据存放于incomingBuffer
与lenBuffer
,待发送的存放于outgoingBuffers
。接下来我们看下处理IO请求的doIO()
方法。
如果是读就绪,则调用readPayload()
处理接收到的数据;如果是写就绪,则调用handleWrite(k)
发送数据。
readPayload()
读就绪事件
最终是将数据提交给服务器实例zkServer进行处理。
handleWrite(k)
写就绪事件
到这里不禁好奇outgoingBuffers
的数据怎么获得的呢?NIOServerCnxn对外提供了sendBuffer(ByteBuffer... buffers)
方法,当需要发送数据给客户端时可调用此方法
process()
NIOServerCnxn实现了Watcher接口,Watcher只有一个方法,即事件的回调方法process()
。
接下来我们详细分析下数据的序列化serialize()
,从中可以看出zookeeper通信的响应协议。
至此,NIOServerCnxn的简单介绍就到此为止,总结一下它的功能,它是服务端与客户端通信的最底层处理,此外,它本身也是一个Watcher。
至此,服务端与客户端的通信环境分析就到此,在NIOServerCnxn.readPayload()
方法中会把来自客户端的请求传递给服务器实例ZookeeperServer处理,zookeeper集群中有三种角色:Leader、Follower、Observer,不同的角色ZookeeperServer实例类型是不一样的,具体得等到选举结束确定角色后才会创建相应的实例,所以,从下文开始分析zookeeper的选举通信以及选举过程。