众所周知,Netty使用了主从Reactor模式来完成CONNECT、ACCEPT、READ、WRITE操作。所以这里就从Reactor角度来分析一下Netty3的线程模型。
- Parent-Reactor
- 服务端Parent-Reactor设计
- 客户端Parent-Reactor设计
- Sub-Reactor
- IO Worker设计
Parent-Reactor
服务端Parent-Reactor设计
在了解了Netty 3的源码后,对它的服务端的线程模型做了简单的总结 :
Boss Executor 、Worker Executor是两个线程池。
Boss Executor中的线程执行的任务是Boss,Worker Executor中的线程执行的任务是Worker。
每个Boss、Worker对象中都独立拥有一个Selector(这里说的独立拥有是指每个Boss、Worker对象都有一个自己的Selector,不存在共用Selector的情况)。所以也可以认为每个Boss、Worker就充当了Dispatcher角色。
Parent-Reactor
Dispatcher:Boss
Demultiplexer:Selector
Handle:ServerSocketChannel (这是Netty中的Channel,包括Pipeline的)
EventType:ACCEPT
EventHandler:交给Sub-Reactor
Dispatcher 的handle_events()方法的过程是:
1)使用Selector选择出有ACCEPT的ServerSocketChannels。
2)调用ServerSocketChannel.accept()来接收客户端的Socket连接。并为接收到的SocketChannel创建相关联的Channel(包括Pipeline、Sink等),注册给一个Worker(Sub-Reactor的Dispatcher),其实质是由这个Worker直接注册给了相关联的Selector。
这个handle_events()过程其实也是Boss任务的内容。
客户端Parent-Reactor线程模型
Dispatcher:Boss
Demultiplexer:Selector
Handle:ClientSocketChannel (这是Netty中的Channel,包括Pipeline的)
EventType:CONNECT
EventHandler:交给Sub-Reactor
Dispatcher 的handle_events()方法的过程是:
1)使用Selector选择出有CONNECT就绪的ClientSocketChannels。
2)调用SocketChannel.finishConnect()来连接到服务端。连接成功后,注册给一个Worker(Sub-Reactor的Dispatcher),其实质是由这个Worker直接注册给了相关联的Selector。
这个handle_events()过程其实也是Boss任务的内容。
Sub-Reactor
客户端、与服务端的Sub-Reactor实现是一样的:
Dispatcher:Worker
Demultiplexer:Selector
Handle:SocketChannel(这是Netty中的Channel)
EventType:READ、WRITE
EventHandler:读写操作
Dispatcher的handle_events()方法的过程是:
1) 使用Selector取出有事件的SocketChannels
2) 遍历SocketChannel,进行读写操作。
读操作执行后,会进入ChannelPipeline中进行处理。在运行过程中的写事件会存储在Channel相关的Queue中等待IOWorker执行写操作。
IO Worker线程的执行逻辑
除了 5、6之外,其它的都是在IOWorker关联的线程中执行的。
了解 Netty的线程模型,对于正确合理使用Netty有很大的帮助。