Netty的Channel过滤器实现原理与Servlet Filter机制一致,它将Channel的数据管道抽象为ChannelPipeline,消息在ChannelPipeline中流动和传递。ChannelPipeline持有I/O事件拦截器ChannelHandler的链表,由ChannelHandler对I/O事件进行拦截和处理,可以方便地通过增删ChannelHandler来实现不同的业务逻辑定制,不需要对已有的ChannelHandler进行修改,能够实现对修改封闭和对扩展的支持。
ChannelPipeline是ChannelHandler的容器,内部维护了一个ChannelHandler的链表和迭代器,它负责ChannelHandler的管理和事件拦截与调度。
ChannelPipeline的主要特性:
ChannelPipeline支持运行态动态的添加或者删除ChannelHandler。例如当业务高峰期需要对系统做拥塞保护时,就可以根据当前的系统时间进行判断,如果处于业务高峰期,则动态地将系统拥塞而保护ChannelHandler添加到当前的ChannelPipeline中,当高峰期过去之后,就可以动态删除拥塞保护ChannelHandler了。
ChannelPipeline是线程安全的,这意味着N个业务线程可以并发地操作ChannelPipeline而不存在多线程并发问题。但是,ChannelHandler却不是线程安全的,这意味着尽管ChannelPipeline是线程安全的,但是用户仍然需要自己保证ChannelHandler的线程安全。
ChannelPipeline的inbound事件:
当发生某个I/O事件的时候,例如链路建立、链路关闭、读取操作完成等,都会产生一个事件,事件在pipeline中得到传播和处理,它是事件处理的总入口。pipeline中以fireXXX命名的方法都是从I/O线程流向用户业务Handler的inbound事件,它们的实现因功能而异,但是处理步骤类似,总结如下。
(1)调用HeaderHandler对应的fireXXX方法;
(2)执行事件相关的逻辑操作。
ChannelPipeline的outbound事件:由用户线程或者代码发起的I/O操作被称为outbound事件。
Pipeline本身并不直接进行I/O操作,最终都是由Unsafe和Channel来实现真正的I/O操作。Pipeling负责将I/O事件通过TailHandler进行调度和传播,最终调用Unsafe的I/O方法进行I/O操作。
ChannelHandler主要分类:
- ChannelPipeling的系统ChannelHnadler,用于I/O操作和对事件进行预处理,对于用户不可见,这类ChannelHandler主要包括HeadHandler和TailHandler;
- 编解码ChannelHandler,包括ByteToMessageCodec、MessageToMessageDecoder等;
- 其他系统功能性ChannelHandler,包括流量整型Handler、读写超时Handler、日志Handler等。
ByteToMessageDeocoder解码器用于将ByteBuf解码成POJO对象。