20211128Java高并发003

netty

netty 曾经升级到 5.0 版本,但是最终因为有问题又回退了,这能从侧面说明只要是软件,是人写的软件都可能有问题,但是遇到问题我们不应该逃避问题,而是正面面对,无论是回退或者是调整都没有问题,重要的是解决问题。

netty 服务器中需要进行完整的流程,其中重要的一步是 bootstrap 启动器,这一步是为了搭配或者串联起来流程,程序流程的串联也是一个技术活怎样优雅的把重要的东西有序串联起来是一个技术活,怎样有序串联也是一个技巧。通过这个启动器,也可以更好的组合几个组件。在我们干活过程中,组合是要远远优于继承的,虽然继承是面向对象的一个重要特性,但是在实际的工程中,组合明显更加灵活,更加方便去更新和优化。

netty 中的 pipeline,组织 netty 中的流水线,他像一个管道将绑定到一个通道的多个 Handler 处理器实例串联起来,形成一条流水线,默认的的实现是一个双向链表,为什么是双向链表主要原因是在 netty 中有两个主要流程,分别是解码流程和编码流程,分别对应输入的接收和解码过程,然后给业务使用,以及发送之前的编码过程, netty 的默认实现使用双向链表达到不同的场景使用不同的方向去应用对应的 decoder 或者 encoder。

bootstrap 有几个核心的依赖,分别是 父子通道、EventLoopGroup(事件轮询组),父子通道值得是,在 netty 中有两种通道,一种通道就是监听连接请求和接收的请求,而子通道则是负责 IO 传输事件的轮询与分发。父子通道与EventLoopGroup比较像 nio 中的 selector 和 Channel 的关系。

netty 中的 channel

通道是 netty 的核心概念之一,代表网络连接,由他负责和对端进行网络通信,不仅可以写数据到对端也可以从对端读取数据,channel 这种角色在喝多框架或者架构中都有体现,无论是 nio 的 channnel ,还是 netty 中的 channel 以及 dart 中的 channel ,以及 kotlin 协程中的 channel ,他们都有一个共性就是为了桥接彼此各种角色,他们有时候是不方便直接通信,更多的时候是为了解耦。

netty 的设计中,有 head context 和 tail context,这两个 context 分别为解码和编码进行调度和收尾工作。

netty 的流水线也可以截断操作,例如某些流水线上在入站的时候某个解码流程或者业务流程明显处理好了这些事件,那么就可以将这些流水线中断,这里通过 channelXxx 去调度后续的连接,这里不调用就自然中断了,或者不调用 Context 的 fireChannelXxx 方法,这里就类似责任链模式。