摘要
Channel、EventLoop 和 ChannelFuture,它们是 Netty 的三大神器,像三位默契配合的舞者,共同构成了 Netty 的核心。Channel 负责数据传输,EventLoop 解决线程同步问题,ChannelFuture 则是控制流的关键。它们的协作,让 Netty 在高并发场景下表现出色。
正文
Netty 架构学习培训 —— Netty 部件与设计方案
Channel、EventLoop 和 ChannelFuture
这一节将对 Channel、EventLoop 和 ChannelFuture 类开展探讨,他们组成在一起,能够 被觉得是 Netty 互联网抽象性的意味着:
- Channel —— Socket
- EventLoop —— 控制流、线程同步解决、高并发
- CHannelFuture —— 多线程通告
1. Channel 插口
Netty 的 Channel 插口相匹配 Java 网络编程技术的 Socket,大幅度降低了立即应用 Socket 类的多元性。除此之外,Channel 也有着别的预订义的完成类:
- EmbeddedChannel:检测 ChannelHandler
- LocalServerChannel:用以同一个 JVM 內部完成 client 和 server 中间的通讯
- NioSocketChannel:多线程的手机客户端 TCP Socket 联接
- NioServerSocketChannel:多线程的服务端 TCP Socket 联接
- NioDatagramChannel:多线程的 UDP 联接
- NioSctpChannel:多线程的手机客户端 Sctp 联接
- NioSctpServerChannel:多线程的 Sctp 服务端联接
- OioSocketChannel:同歩的手机客户端 TCP Socket 联接
- OioServerSocketChannel:同歩的服务端 TCP Socket 联接
- OioDatagramChannel:同歩的 UDP 联接
- OioSctpChannel:同歩的 Sctp 服务端联接
- OioSctpServerChannel:同歩的手机客户端 TCP Socket 联接
2. EventLoop 插口
EventLoop 用以解决联接的生命期中所产生的事情,下面的图表明了 Channel、EventLoop、Thread 及其 EventLoopGroup 中间的关联
这种关联是:
- 一个 EventLoopGroup 包括一个或好几个 EventLoop
- 一个 EventLoop 在它的生命期内只和一个 Thread 关联
- 全部由 EventLoop 解决的 IO 事情都将在它特有的 Thread 上被解决
- 一个 Channel 在它的生命期内只申请注册一个 EventLoop
- 一个 EventLoop 很有可能会被分派到一个或好几个 Channel
3. ChannelFuture 插口
Netty 全部的 IO 实际操作全是多线程的,一个实际操作很有可能不容易马上回到結果,因而大家必须一种用以在以后的某一时间点明确其結果的方式。Netty 给予了 ChannelFuture 插口,其 addListener() 方式申请注册一个 ChannelFutureListener,便于在某一实际操作过去进行时(不管是不是取得成功0获得通告)
ChannelHandler 和 ChannelPipeline
1. ChannelHandler 插口
ChannelHandler 能够 当作是承担解决入站和出站数据信息的运用程序结构的器皿,比如将数据信息从一个格式转化为另一种文件格式,解决抛出去的出现异常这些。ChannelInboundHandler 是一个常常应用的子插口,这类种类的 ChannelHandler 接收益站事情和数据信息,这种数据信息接着将被你的领域模型锁解决。如果你要想给手机客户端推送回应时,还可以从 ChannelInboundHandler 冲洗数据信息,一般应用软件的领域模型一般停留在一个或是好几个 ChannelInboundHandler 中
2. ChannelPipeline 插口
ChannelPipeline 为 ChannelHandler 链给予了器皿,并界定了用以在该链上散播入站和出站事情流的 API。当 Channel 被建立时,它会被全自动地分派到它专享的 ChannelPipeline
ChannelHandler 安裝到 ChannelPipeline 中的全过程以下所显示:
- 一个 ChannelInitializer 的完成被申请注册到 ServerBootstrap 中
- 当 ChannelInitializer.initChannel() 方式被启用时,ChannelInitializer 将在 ChannelPipeline 中安裝一组自定的 ChannelHandler
- ChannelInitializer 将它自身从 ChannelPipeline 中清除
ChannelHandler 能够 当作是解决来往 ChannelPipeline 事情(包含数据信息)的一切编码的通用性器皿,使事情流历经 ChannelPipeline 是 ChannelHandler 的工作中,在应用软件的复位或是正确引导环节被安裝。这种 ChannelHandler 接受事情、实行所完成的领域模型,并将数据信息传送给链中的下一个 ChannelHandler。他们的实行次序由他们被加上的次序所决策。事实上,ChannelPipeline 便是这种 ChannelHandler 的编辑次序
当 ChannelHandler 被加上到 ChannelPipeline 时,它会被分派一个 ChannelHandlerContext,其意味着了 ChannelHandler 和 ChannelPipeline 中间的关联,尽管这一目标能够 被用以获得最底层的 Channel,但它或是关键用以写下站数据信息
在 Netty 中有二种推送信息的方法,能够 立即写到 Channel 中,还可以提到和 ChannelHandler 关联的 ChannelHandlerContext 目标中。前一种方法可能造成信息从 ChannelPipeline 的尾部逐渐流动性,后面一种将造成信息从 ChannelPipeline 中的下一个 ChannelHandler 逐渐流动性
伺服电机和视频解码器
如果你根据 Netty 推送或是接受一个信息时,便会产生一次数据交换。入站信息会被编解码,即从字节转换成另一种文件格式,一般是一个 Java 目标。如果是出站信息,则会产生反过来方位的变换,从当今文件格式被编号为字节数。因此,Netty 为伺服电机和视频解码器给予了不一样种类的内部类,这种基类的名字将类似 ByteToMessageDecoder 或 MessageToByteEncoder。针对一些独特种类,很有可能还会继续有 ProtobufEncoder 和 ProtobufDecoder 那样的名字,用于适用 Google 的 Protocol Buffers
应用 Netty 给予的伺服电机/视频解码器,你能发觉针对入站数据信息而言,channelRead 方式/事情早已被调用。针对每一个从行站 Channel 载入的信息,将启用调用后的 channelRead 方式。接着,它将启用视频解码器给予的 decode() 方式,将已编解码的字节数发送给 ChannelPipeline 中的下一个 ChannelInboundHandler。出站信息是相反的,伺服电机将信息变换为字节数,并将他们发送给下一个 ChannelOutboundHandler
正确引导
Netty 的正确引导类为应用软件的传输层配备给予了器皿,这涉及到将一个过程关联到某一特定的端口号,或是将一个过程联接到另一个运作在某一特定服务器的特定端口号上的过程。一般大家把前边的测试用例称之为正确引导一个网络服务器,后边的测试用例称之为正确引导一个手机客户端。因而,有二种种类的正确引导:一种用以手机客户端(Bootstrap),而另一种(ServerBootstrap)用以网络服务器
二种种类的正确引导类差别以下:
-
ServerBootstrap 将关联到一个端口号,由于网络服务器务必要监视联接,而 Bootstrap 则是由要想联接到远程控制连接点的手机客户端应用软件应用
-
正确引导一个手机客户端只必须一个 EventLoopGroup,可是一个 ServerBootstrap 则必须2个。由于网络服务器必须2组不一样的 Channel,第一组只包括一个 ServerChannel,意味着网络服务器本身已关联到某一本地端口的已经监视的tcp协议,而第二组将包括全部已建立的用于解决传到手机客户端联接的 Channel
与 ServerChannel 关联的 EventLoopGroup 将分派一个承担为传到联接要求建立 Channel 的 EventLoop。一旦联接被接纳,第二个 EventLoopGroup 便会给它的 Channel 分派一个 EventLoop
关注不迷路
扫码下方二维码,关注宇凡盒子公众号,免费获取最新技术内幕!
评论0