一起说说Netty责任链,责任链这块是netty运行机制的核心,一起来完整的了解下netty的责任链。
(一)责任链模式
介绍
责任链模式(Chain of Responsibility Pattern) 为请求创建了一个处理对象的链。一个请求过来后,就交给一个责任链进行调用。在责任链里面定义很多很多的handler,具体请求这个程序的handler,请求者不关心,多少个步骤,多少次,只负责发送到责任链上,请求传递的细节不关心。
实现责任链模式
处理器抽象类,具体的处理器实现类,保存处理器信息,处理执行。
源码分析
(二)Netty中的ChannelPipeline责任链
介绍
pipeline管道保存了通道所有处理器信息,创建channel时自动创建一个专有的pipeline,入站事件和出站事件会调用pipeline上的处理器。
入站事件和出站事件
入站事件:通常指IO线程生成了入站数据
(通俗理解:从socket底层自己往上冒上来的事件都是入站)
比如EventLoop收到selector的OP_READ事件,入站处理器调用socketChannel.read(ByteBuffer)接受到数据后,这将导致通道的ChannelPipeline中包含的下一个中的channelRead方法被调用
出站事件:通常指IO线程执行实际的输出操作
(通俗理解:想主动往socket底层操作的事件的都是出站)
比如bind方法用时请求server socket绑定到给定的SocketAddress,这将导致通道的ChannelPipeline中包含的下一个出站处理器中的bind方法被调用
Nettty中定义的事件
Pipeline中的handler是什么
ChannelHeadler
用于处理I/O事件或者拦截I/O操作,并转发到ChannelPipeline中下一个处理器。这个顶级接口定义功能很弱,实际使用时会去实现下面两大子接口:处理入站I/O事件的ChannelInboundHandler、处理出站I/O操作的ChannelOutboundHandler
适配器类
为了方便开发,避免所有handler去实现一遍接口方法,Netty提供了简单的实现类:
ChannelInboundHandlerAdapter处理入站I/O事件
ChannelOutboundHandlerAdapter处理出站I/O事件
ChannelDuplexHandler支持同时处理入站和出站事件
ChannelHandlerContext
实际存储在Pipeline中的并非是ChannelHandler,而是上下文对象。将Handler包裹在上下文对象中,通过上下文对象与它所属的ChannelPipeline交互,向上或向下传递事件或者修改pipeline都是通过上下文对象。
那么如何维护Pipeline中的handler呢
ChannelPipeline是线程安全的,ChannelHandler可以在任何时候添加或者删除。例如你可以在即将交换敏感信息时插入加密处理程序,并在交换后删除它。一般操作,初始化的时候增加进去,较少删除。下面是Pipeline中管理的API
除了register方法还有bind方法,bind方法时出站事件执行顺序和入站事件相反
请求过来以后又是如何处理的呢?我们通过Accept事件获取请求,所以我们应该去看accept入站事件是如何处理的,
PS:用户在管道中有一个或者多个channelhandler来接收I/O事件(例如读取)和请求I/O操作(例如写入和关闭)一个典型的服务器在每个通道的管道中都有以下处理程序,但是根据协议和业务逻辑的复杂性和特征,可能会有所不同。
协议解码器--将二进制数据(例如ByteBuf)转换为Java对象
协议编码器--将java对象转化为二进制数据
业务逻辑处理程序--执行实际的业务逻辑(例如访问数据库)
领取专属 10元无门槛券
私享最新 技术干货