Netty分析之inBound,outBound,异常事件在pipeline中的传播

inBound事件spa

  当发生某个IO事件的时候,例如链路创建,链路关闭,读取操做完成(register,read,active)等,都会产生一个事件,事件在pipeline中传播和处理。pipeline中以fireXXX命名的方法都是从IO线程向用户业务Handler的inBound事件,它们的实现因功能而异,可是处理步骤相似。以下:线程

(1)调用HeadHandler对应的fireXXX方法。事件

(2)执行事件相关的逻辑操做。ip

  当调用ChannelHandlerContext.fireXXX(fireChannelRead())方法的时候,事件会从当前节点向下进行传播,就是找到下一个ChannelInBoundHandler,而后调用ChannelInBoundHandler的channelXXX方法,若是不覆盖channelXXX方法的话,默认会将这个消息在pipeline上从头至尾进行传播,最后会调用到Tail节点的channelXXX方法,若是说有消息一直调用到Tail节点的channelXXX方法,说明前面的channelHandler没有处理消息,使得消息一直到了尾节点,尾节点须要进行必定的释放,防止内存泄漏。内存

  SimpleChannelInBoundHandler的channelRead0方法会帮助自动释放ByteBuf,它的channelRead方法调用channelRead0()而且释放ByteBuf。pip

outBound事件io

   由用户线程或者代码发起的IO操做被称作outBound事件。ChannelOutBoundHandler的添加顺序和事件传播的顺序是相反的。而outBound事件是寻找下一个ChannelOutBoundHandler,调用该handler的方法,最终会从Tail节点传播到Head节点。内存泄漏

  总结:每次使用pipeline传播调用方法时,是从头结点或者尾节点开始传播,而使用ChannelHandlerContext则是从当前节点开始传播。exception

异常传播channel

  异常的传播并不区分是inBoundHandler仍是outBoundHandler,异常都会在上面进行传播。异常的传播顺序是和handler添加的顺序相关(同样)。默认状况下异常的传播是直接拿到当前节点的下一个节点,最终会传播到Tail节点的exceptionCaught(),Tail节点最终会打印这个exception,通知这个异常并无被处理。若是说咱们须要对异常作一个处理的话,最好在pipeline最后添加一个异常处理器,最终能够对异常进行一个统一的处理。

相关文章
相关标签/搜索