Java学习总结(2.2.2) 责任链模式

精贴 置顶
1760 0
作者:      发布时间: 2020-04-20 15:41:20

设计模式 - 责任链模式


责任链模式( Chain of Responsibility Pattern)为请求创建了一个处理对象的链。

发起请求和具体处理请求的过程进行解耦:职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递。


实现责任链

实现责任链模式4个要素:

处理器抽象类、具体的处理器实现类、保存处理器信息、处理执行



Netty中的ChannelPipeline责任链

Pipeline管道保存了通道所有处理器信息。创建新 channele时自动创建一个专有的 pipeline入站事件和出站操作会调用 pipeline上的处理器



入站事件与出站事件

入站事件:通常指I/O线程生成了入站数据。(通俗理解:从 socket底层自己往上冒上来的事件都是入站)比如 Eventloop收到 selector的OP_READ事件,入站处理器调用 socketChannel.read( Bytebuffer)接收到数据后,这将导致通道的 Channelpipeline中包含的下一个中的 channelread方法被调用。

出站事件:经常是指O线程执行实际的输出操作。(通俗理解:想主动往 socket底层操作的事件的都是出站)比如bind方法用意是请求 server socket绑定到给定的 Socketaddress,这将导致通道的Channelpipeliner中包含的下一个出站处理器中的bind方法被调用。



Netty中事件的定义

inbound入站事件

事件描述
fireChannelRegisteredchannel注册事件
fireChannelUnregisteredchannel解除注册事件
firechannelActivechannel活跃事件
fireChannelInactivechannel非活跃事件
fireExceptionCaught异常事件
fireUserEventTriggered用户自定义事件
fireChannelReadchanne读事件
fireChannelReadCompletechanne读完成事件
fireChannelWritabilityChangedChannel写状态变化事件




outbound出站事件


事件描述
bind端口绑定事件
connect连接事件
disconnect断开连接事件
close关闭事件
deregister解除注册事件
flush刷新数据到网络事件
read读事件,用于注册OP_READ到 selector
write写事件
writeAndFlush写出数据事件



Pipeline中的handler是什么


Channelhandler:

用于处理I/O事件或拦截I/O操作,并转发到 ChannelPipeline中的下一个处理器。

这个顶级接口定义功能很弱,实际使用时会去实现下面两大子接口:

处理入站I/O事件的 Channellnboundhandler、处理出站I/O操作的 Channeloutboundhandler


适配器类:

为了开发方便,避免所有 handler去实现一遍接口方法,Netty提供了简单的实现类:

ChannellnboundHandlerAdapter处理入站I/O事件

ChannelOutboundHandlerAdapter来处理出站I/O操作

Channelduplexhandler来支持同时处理入站和出站事件


Channelhandlercontext:

实际存储在 Pipeline中的对象并非 Channelhandler,而是上下文对象。将 handler,包裏在上下文对象中,通过上下文对象与它所属的 Channelpipeline交互,向上或向下传递事件或者修改 pipeline都是通过上下文对象。


维护Pipeline中的handler

Channelpipeline是线程安全的, Channelhandleri可以在任何时候添加或删除。例如,你可以在即将交换敏感信息时插入加密处理程序,并在交换后删除它。一般操作,初始化的时候增加进去,较少删除。下面是 Pipeline中管理 handlers的API

方法名称描述
addFirst最前面插入
addLast最后面插入
addBefore插入到指定处理器前面
addAfter插入到指定处理器后面
remove移除指定处理器
removeFirst移除第一个处理器
removeLast移除最后一个处理器
replace替换指定的处理器



handler的执行分析

ChannelDuplexHandler 5
Outbound Handler 4
Outbound Handler 3
Inbound Handler 2
Inbound Handler 1


当入站事件时,执行顺序是1、2、3、4、5

当出站事件时,执行顺序是5、4、3、2、1

在这一原则之上, Channelpipeline在执行时会进行选择3和4为出站处理器,因此入站事件的实际执行是:1、2、5

1和2为入站处理器,因此出站事件的实际执行是:5、4、3


不同的入站事件会触发 handler.不同的方法执行:

上下文对象中fire开头的方法,代表入站事件传播和处理其余的方法代表出站事件的传播和处理。



分析 registered入站事件的处理

1)bind(端口):AbstractBootstrap

2)创建和初始化Channel

3)注册到EventLoop中的Selector上


注2:

通道创建时构建一个 pipeline,头尾分别是 Head Context..Tail Context

init()增加了一个 Channellnitializer,这个 handler用于通道初始化,我们自己的相关初始化定义都是通过它执行的。

注3:

config(). group(). register() registered成功之后

触发 Channellnitializer.channelRegistered

初始化 Handler执行一次之后,会把自己从pipeline中除掉



分析bind出站事件的处理

1) bind(端口): Abstractbootstrap

2) 创建和初始化Channel

3) 注册到 EventLoop中的 Selector上

4) dobind0()-> channel.bind

5) pipeline.bind

出站操作

6) ServerSocketChannel

7) HeadContext.bind

8) AbstractUnsafe.bind

9) NioServerSocketChannel.doBind



分析 accept入站事件的处理


1) EventLoop轮询到accept事件

2) NioMessageUnsafe.read

3) NioServerSocketChannel.doReadMessages

4) 传播fireChannelRead事件

入站操作自底向上

5) 完成注册后的ChannlPipeline

6)channelRead


这是一个分配的过程, main Group负责accept,然后分配sub Group负责read



分析read入站事件的处理

pipeline分析的关鍵4要素:

什么事件、有哪些处理器、哪些会被触发、执行顺序


1) EventLoop轮询到op_read事件

2) NioByteUnsafe.read 读取内容

3) fireChannelRead、readComplete

入站操作

4) socketChannel的ChannelPipeline



小结

用户在管道中有一个或多个 channelhandler来接收I/O事件(例如读取)和请求I/O操作(例如写入和关闭)。

一个典型的服务器在每个通道的管道中都有以下处理程序,但是根据协议和业务逻辑的复杂性和特征,可能会有所不同:

协议解码器一一将二进制数据(例如 Bytebuf转换为Java对象。

协议编码器一一将Java对象转换为二进制数据。

业务逻辑处理程序一一执行实际的业务逻辑(例如数据库访问)。


责任链设计模式的运用,保证了Netty的高度可拓展性!


标签:

每日一句

如果花了足够多的时间考虑你的目标,你就能用自己的心看到、摸到、尝到和闻到那个目标,你不会轻易放弃。实现目标的欲望会给你足够的毅力克服哪怕是最令人生畏的障碍。在真的取得成功之前,你应该已经在头脑中达成目标。这样你就能承受任何暂时的痛苦,实现自己的梦想。

标签云

vue
最近综合
情绪巨婴是什么 12.18
普通蛋糕做法 05.31
玉米烤肠芝士面包做法 05.31
Mysql安装教程 - 绿色版 06.18
我们学习知识为什么总是忘记呢?【学习金字塔】 05.12
Typora开发版⽆法使⽤解决⽅法 05.04
为什么无知者越自信? -- 达克效应 05.10
马斯洛需求层次理论 04.29
随机综合
Java学习总结(2.1.1) TCP/UDP协议 04.17
Java学习总结(2.2.2) 责任链模式 04.20
Java学习总结(1.2.2) 线程安全之原子操作 03.20
中间件1.2.2-ActiveMQ支持的消息协议讲解 04.23
iPhone 6与iPhone 6 Plus正式开放预订 09.17
马斯洛需求层次理论 04.29
Java学习总结(2.1.3) NIO非阻塞网络编程三大核心理念 04.17
中间件1.2.4-ActiveMQ持久化原理和事务机制 04.29