共计 1660 个字符,预计需要花费 5 分钟才能阅读完成。
前言
在上一篇文章中:Netty:ChannelPipeline 和 ChannelHandler 为什么会鬼混在一起?– 掘金 (juejin.cn)
曾经提到了 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 的增加和删除都十分不便,他具备热插拔性。