Zookeeper源码分析--NIOServerCnxnFactory
NIOServerCnxnFactory基于NIO实现了一个多线程的ServerCnxnFactory,线程间的通信都是通过queue来完成的。NIOServerCnxnFactory包含的线程如下:
- 1个accept线程
NIOServerCnxnFactory.AcceptThread
,用来监听端口并接收连接,然后把该连接分派给selector线程。 - N个selecotr线程
NIOServerCnxnFactory.SelectorThread
,每个selctor线程平均负责1/N的连接。使用N个selector线程的原因在于,在大量连接的场景下,select()操作本身可能会成为性能瓶颈。 - N个worker线程
protected WorkerService workerPool;
,用来负责socket的读写。如果N为0,那么selector线程自身会进行socket读写。 - 1个管理连接的线程
NIOServerCnxnFactory.ConnectionExpirerThread
,用来关闭空闲而且没有建立session的连接。
这几种线程相互配合的原理如下:
- AcceptThread和SelectorThread都继承自NIOServerCnxnFactory.AbstractSelectThread,AbstractSelectThread会在内部维护一个Selector。因此AcceptThread和SelectorThread各自会维护一个Selector。
- 一般的流程大约是:
- AcceptThread监听新连接,并根据轮询法,选择一个SelectorThread,将新连接置于后者的acceptedQueue(LinkedBlockingQueue)中。
- 后者从acceptedQueue中取出连接,将读写事件注册在自己的Selector上,并监听读写事件,将触发的连接包装成IOWorkRequest,交给workerPool线程池服务运行。
- IOWorkRequest的doWork会被线程池运行,在这之中,会调用cnxn.doIO调用NIOServerCnxn的方法。
- 后者会读取4字节int数据,并交给CommandExecutor找到对应的命令AbstractFourLetterCommand,根据命令模式,去执行。这些命令可能会需要ZooKeeperServer和ServerCnxnFactory的协调。
- 关于过期连接的关闭,一般由
private ExpiryQueue<NIOServerCnxn> cnxnExpiryQueue;
维护,并由ConnectionExpirerThread周期性检查、关闭过久未被激活的连接。
网友评论