Channel,EventLoop,ChannelPipeline,EventExecutor和ChannelHandler之间的关系
每一个channel持有一个eventLoop, channel.unsafe的方法会在这个eventLoop中执行。那么问题来了,使用add方法向channelPiple中添加一个channelHandler,这个handler的方法在哪里执行呢?下面以addLast为例看看添加方法。
ChannelPipeline addLast(ChannelHandler... handlers)
ChannelPipeline addLast(EventExecutorGroup group, ChannelHandler... handlers)
ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler)
channelPiple负责为每一个新添加的handler分配一个eventExecutor。若是你调用了带grop参数的方法添加handler ,channelPiple会从group中取出一个eventExecutor分配给这个handler, 这时handler中的回调方法会在这个eventExecutor线程中执行,不然channelPiple会把channel的eventLoop当成eventExecutor分配给这个handler,这时这个handler的回调方法会在eventLoop的线程中执行。这个二者有什么不一样呢?若是没你没有给handler指定group,它将会和channel的I/O操做共享线程资源,它能获得多少线程资源取决于eventLoop的ioRatio属性的设置,执行时间过长的handler的回调方法会影响I/O操做。若是指定了group,handler的回调方法和channel的I/O操做将会被隔离到不一样的线程中。在高并发状况下,强烈建议为不一样功能的handler指定不一样的group。
每一个channel实例在建立的时候,它本身负责建立一个channelPiple实例。随后这个channel会被注册到一个eventLoop中,eventLoop负责处理channel上触发的I/O事件,把I/O事件转换成对channel.unsafe方法的调用。unsafe负责作实际的I/O操做,根据须要调用channelPiple触发事件。channelPiple依次调用合适的handler处理事件。这里的"依次”和“合适”的含义是:
- 若是是inbound事件,会从头至尾按顺序调用双向链表上的ChannelInboundHandler类型的handler。
- 若是是outbound事件,会从尾到头按顺序调用双向链表上的ChannelOutboundHandler类型的handler。
piplePile确保一个handler调用始终在一个惟一的eventExecutor中,这个eventExecutor多是channel的eventLoop,也多是从用户指定的eventExecutorGroup中分配到的一个executor。