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 则需要两个。因为服务器需要两组不同的 Channel,第一组只包含一个 ServerChannel,代表服务器自身已绑定到某个本地端口的正在监听的套接字,而第二组将包含所有已创建的用来处理传入客户端连接的 Channel

    与 ServerChannel 相关联的 EventLoopGroup 将分配一个负责为传入连接请求创建 Channel 的 EventLoop。一旦连接被接受,第二个 EventLoopGroup 就会给它的 Channel 分配一个 EventLoop

Netty 框架学习 —— Netty 组件与设计的更多相关文章

  1. NetCore Netty 框架 BT.Netty.RPC 系列随讲 二 WHO AM I 之 NETTY/NETTY 与 网络通讯 IO 模型之关系?

    一:NETTY 是什么? Netty 是什么?  这个问题其实百度上一搜一堆. 这是官方话的描述:Netty 是一个基于NIO的客户.服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个 ...

  2. Netty 框架学习 —— 引导

    概述 前面我们学习了 ChannelPipeline.ChannelHandler 和 EventLoop 之后,接下来的问题是:如何将它们组织起来,成为一个可实际运行的应用程序呢?答案是使用引导(B ...

  3. Netty 框架学习 —— 编解码器框架

    编解码器 每个网络应用程序都必须定义如何解析在两个节点之间来回传输的原始字节,以及如何将其和目标应用程序的数据格式做相互转换.这种转换逻辑由编解码器处理,编解码器由编码器和解码器组成,它们每种都可以将 ...

  4. Netty 框架学习 —— 第一个 Netty 应用

    概述 在本文,我们将编写一个基于 Netty 实现的客户端和服务端应用程序,相信通过学习该示例,一定能更全面的理解 Netty API 该图展示的是多个客户端同时连接到一台服务器.客户端建立一个连接后 ...

  5. Netty 框架学习 —— EventLoop 和线程模型

    EventLoop 接口 Netty 是基于 Java NIO 的,因此 Channel 也有其生命周期,处理一个连接在其生命周期内发生的事件是所有网络框架的基本功能.通常来说,我们使用一个线程来处理 ...

  6. Netty 框架学习 —— ByteBuf

    概述 网络数据的基本单位总是字节,Java NIO 提供了 ByteBuffer 作为它的字节容器,但这个类的使用过于复杂.Netty 的 ByteBuf 具有卓越的功能性和灵活性,可以作为 Byte ...

  7. Netty 框架学习 —— 单元测试

    EmbeddedChannel 概述 ChannelHandler 是 Netty 程序的关键元素,所以彻底地测试它们应该是你的开发过程中的一个标准部分,EmbeddedChannel 是 Netty ...

  8. Netty 框架学习 —— 预置的 ChannelHandler 和编解码器

    Netty 为许多提供了许多预置的编解码器和处理器,几乎可以开箱即用,减少了在烦琐事务上话费的时间和精力 空闲的连接和超时 检测空闲连接以及超时对于释放资源来说至关重要,Netty 特地为它提供了几个 ...

  9. Netty 框架学习 —— 添加 WebSocket 支持

    WebSocket 简介 WebSocket 协议是完全重新设计的协议,旨在为 Web 上的双向数据传输问题提供一个切实可行的解决方案,使得客户端和服务器之间可以在任意时刻传输消息 Netty 对于 ...

随机推荐

  1. (数据科学学习手札118)Python+Dash快速web应用开发——特殊部件篇

    本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 这是我的系列教程Python+Dash快速web ...

  2. 【OOM】记录一次生产上的OutOfMemory解决过程

    一.项目架构 SpringCloud  Dalston.SR1 + SpringBoot 1.5.9 + Mysql +Redis + RabbitMQ 所有的业务模块的应用服务都部署在同一个服务器, ...

  3. hdu2722 简单最短路,处理好输入就行

    题意:       从左上角走到右下角,有的最短时间,每段路径的长度都是2520,每段上都有自己的限制速度,方向. 思路:      直接写就行了,就是个最短路,权值是2520/限制,输入的时候细心点 ...

  4. LA2678最短子序列

    题意:       给你一个正整数序列,问你在里面找到一个最短的子序列,要求子序列的和大于等于k,输出序列长度. 思路:       这个序列的每个数字都是正整数,那么就比较好想了,我们可以直接枚举终 ...

  5. Python中的BeautifulSoup模块

    目录 BeautifulSoup Tag NavigableString BeautifulSoup Comment 遍历文档树 直接子节点 所有子孙节点 ​ 节点内容 搜索标签 CSS选择器 Bea ...

  6. [CTF]ROT5/13/18/47位移密码

    [CTF]ROT5/13/18/47位移密码 ---------------转换网站 https://www.qqxiuzi.cn/bianma/ROT5-13-18-47.php ROT5:只对数字 ...

  7. ecloud云主机限速相关配置说明

    目前与云主机限速相关的内容共有三处: neutron qos-xxx命令,通过neutron qos的形式为云主机port绑定相应的网络限速策略(对应弹性公网IP) 通过flavor对云主机进行默认限 ...

  8. idea中properties配置文件没有代码提示及代码高亮问题解决方案

    更多精彩关注微信公众号 1.解决properties文件没有代码提示问题:首先,单击项目结构按钮,如下图: 然后,给项目添加Spring依赖支持,如下图: 2.解决代码不高亮问题:     代码不高亮 ...

  9. 【转】风控中的特征评价指标(三)——KS值

    转自:https://zhuanlan.zhihu.com/p/79934510 风控业务背景 在风控中,我们常用KS指标来评估模型的区分度(discrimination).这也是风控模型同学最为追求 ...

  10. CAS指令

    原文链接:https://www.jianshu.com/p/00edb3d74a33   CAS是CPU的一条指令,其具有原子性,原子性是由CPU硬件层面保证的.   CAS原语有三个操作数--内存 ...