往期相关文章:
- IO:堵塞和非堵塞、同步和异步 – ()
- 序列化和反序列化 – ()
- Netty框架内的瑰宝:ByteBuf – ()
- Netty:遇到TCP发送缓冲区满了 写半包操作该怎么处理 – ()
- Netty:与AbstractByteBuf渐进式步进截然不同的扩容规矩–AdaptiveRecvByteBufAllocator – ()
前语
在上一篇文章中:Netty:ChannelPipeline和ChannelHandler为什么会鬼混在一起? – ()
已经提到了ChannelPipeline里边维护了ChannelHandler的链表,ChannelHandler首要就是担任里边的时刻进行拦截和处理。
本篇首要介绍:
-
ChannelHandler
功用说明 - 接口的透传规划
- 依据职责链形式的ChannelHandler完成的热插拔功用
ChannelHandler功用说明
依据职责链形式完成,担任对IO事情进行拦截和处理, 也能够停止事情的传递。
ChannelHandler支撑注解,Netty供给了2个:
-
Sharable
:多个ChannelPipline公用同一个ChannelHandler -
Skip
:被Skip注解的办法不会被调用
ChannelHandlerAdapter
削减臃肿的代码,只需求完成我感兴趣的事情就好,不感兴趣的不用完成
关于大多数ChannelHandler只会关怀很少一部分事情,其他事情就会忽略交给下一个ChannelHandler处理。
这就会有一个问题就是,用户自己界说的ChannelHandler有必要完成ChannelHandler
的一切接口,包括他不关怀的那些事情处理接口,这会让代码显得很臃肿。
事情透传
为了处理这个问题,Netty供给了ChannelHandlerAdapter
,他的一切接口完成都是事情透传的。
透传:这个概念是通讯传输的,指的是不论事务内容怎么变,只担任将内容从来历,传输到目的地
在这儿,就是他完成了一个空的办法,留了个钩子Hook,里边没有处理任何事情,如果子类需求有相关需求的逻辑,重写就能够,没有也不需求完成。
可是后面Netty高版本之后,ChannelHandler也只有2个需求完成的办法:
handlerAdded
handlerRemoved
不过它供给了这个Adaptor
的思路也是十分不错的。
ChannelHander热插拔性
ChannelPipeline
支撑运行态动态地添加或许删去ChannelHandler
首先解释一下什么是热插拔,关于玩键盘的人来说应该是再了解不过了。
感谢百度百科对本篇文章的大力资助。
关于程序来说其实就是,支撑在程序运行时动态地去修改。看到这儿是不是想到很多相关的技能?
- ASM字节码
- 反射
- AOP
- 动态代理
- …
支撑动态可插拔:意味着,我们能够随时依据事务场景进行调整Handler的处理逻辑。
流量压力其实也是符合
28原则
,20%的时刻可能承受的是一天80%的流量压力,80%的时刻其实仅仅承当一天流量的20%。
因而,我们能够在事务高峰期的时候,动态地将体系拥塞保护、或许是一些限流的ChannelHandler添加到当时的ChannelPipeline中。
然后等流量压力小了之后,再把这些ChannelHandler
给删掉
特别的,一些事务场景中Handler之间具有次序性
比如HandlerB,需求在HandlerA前面执行
ChannelPipleline
支撑在任意地方添加,他有:
addFirts
addBefore
addLast
这些办法,在指定位置添加或许删去ChannelHandler
线程安全性
ChannelPipeline
是线程安全的。N个事务线程能够并发操作CHannelPipeline而不存在多线程并发问题,这个是框架完成的。(他是通过简略的加锁synchronized
失望锁来完成的)
可是ChannelHandler
不是线程安全的。这个还需求通过user-code
,程序员来编写代码自己确保。
总结
ChannelHandler只介意自己关怀的事情,可是在父类里边界说了一切事情的处理办法,为了削减代码的臃肿,子类不需求完成一切父类的抽象办法,Netty把这些办法界说成事情透传。
Netty的ChannelPipeline
依据职责链的规划特性,他是一个链表的形式存在,所以关于ChannelHandler
的添加和删去都十分方便,他具有热插拔性。
来都来了,点个赞再走吧彦祖,这对我来说十分重要!
本文正在参与「金石计划」