从 Spring Boot 程序启动深入理解 Netty 异步架构原理( 二 )


可以通过 ChannelInboundHandlerAdapter 实现,具体内容如下:

从 Spring Boot 程序启动深入理解 Netty 异步架构原理

文章插图
处理来自客户端的请求
从上面的代码可以看出,服务端处理的代码包含了三个方法 。这三个方法都是根据事件触发的 。
他们分别是:
  • 当接收到消息时的操作,channelRead 。
  • 消息读取完成时的方法,channelReadComplete 。
  • 出现异常时的方法,exceptionCaught 。
客户端代码
客户端和服务端的代码基本相似,在初始化时需要输入服务端的 IP 和 Port 。
从 Spring Boot 程序启动深入理解 Netty 异步架构原理

文章插图
 
同样在客户端启动函数中包括以下内容:
从 Spring Boot 程序启动深入理解 Netty 异步架构原理

文章插图
 
客户端启动程序的顺序:
  • 创建 Bootstrap 。
  • 指定 EventLoopGroup 用来监听事件 。
  • 定义 Channel 的传输模式为 NIO(Non-BlockingInputOutput) 。
  • 设置服务器的 InetSocketAddress 。
  • 在创建 Channel 时,向 ChannelPipeline 中添加一个 EchoClientHandler 实例 。
  • 连接到远程节点,阻塞等待直到连接完成 。
  • 阻塞,直到 Channel 关闭 。
  • 关闭线程池并且释放所有的资源 。
客户端在完成以上操作以后,会与服务端建立连接从而传输数据 。同样在接受到 Channel 中触发的事件时,客户端会触发对应事件的操作 。
从 Spring Boot 程序启动深入理解 Netty 异步架构原理

文章插图
 
例如 Channel 激活,客户端接受到服务端的消息,或者发生异常的捕获 。
从代码结构上看还是比较简单的 。服务端和客户端分别初始化创建监听和连接 。然后分别定义各自的 Handler 处理对方的请求 。
从 Spring Boot 程序启动深入理解 Netty 异步架构原理

文章插图
服务端/客户端初始化和事件处理
Netty 核心组件通过上面的简单例子,发现有些 Netty 组件在服务初始化以及通讯时被用到,下面就来介绍一下这些组件的用途和关系 。
①Channel
通过上面例子可以看出,当客户端和服务端连接的时候会建立一个 Channel 。
这个 Channel 我们可以理解为 Socket 连接,它负责基本的 IO 操作,例如:bind(),connect(),read(),write() 等等 。
简单的说,Channel 就是代表连接,实体之间的连接,程序之间的连接,文件之间的连接,设备之间的连接 。同时它也是数据入站和出站的载体 。
②EventLoop 和 EventLoopGroup
既然有了 Channel 连接服务,让信息之间可以流动 。如果服务发出的消息称作“出站”消息,服务接受的消息称作“入站”消息 。那么消息的“出站”/“入站”就会产生事件(Event) 。
例如:连接已激活;数据读取;用户事件;异常事件;打开链接;关闭链接等等 。
顺着这个思路往下想,有了数据,数据的流动产生事件,那么就有一个机制去监控和协调事件 。
这个机制(组件)就是 EventLoop 。在 Netty 中每个 Channel 都会被分配到一个 EventLoop 。一个 EventLoop 可以服务于多个 Channel 。
每个 EventLoop 会占用一个 Thread,同时这个 Thread 会处理 EventLoop 上面发生的所有 IO 操作和事件(Netty 4.0) 。
从 Spring Boot 程序启动深入理解 Netty 异步架构原理

文章插图
EventLoop 与 Channel 关系
理解了 EventLoop,再来说 EventLoopGroup 就容易了,EventLoopGroup 是用来生成 EventLoop 的,还记得例子代码中第一行就 new 了 EventLoopGroup 对象 。
一个 EventLoopGroup 中包含了多个 EventLoop 对象 。
从 Spring Boot 程序启动深入理解 Netty 异步架构原理

文章插图
创建 EventLoopGroup
EventLoopGroup 要做的就是创建一个新的 Channel,并且给它分配一个 EventLoop 。
从 Spring Boot 程序启动深入理解 Netty 异步架构原理

文章插图
EventLoopGroup,EventLoop 和 Channel 的关系
在异步传输的情况下,一个 EventLoop 是可以处理多个 Channel 中产生的事件的,它主要的工作就是事件的发现以及通知 。
相对于以前一个 Channel 就占用一个 Thread 的情况 。Netty 的方式就要合理多了 。
客户端发送消息到服务端,EventLoop 发现以后会告诉服务端:“你去获取消息”,同时客户端进行其他的工作 。
当 EventLoop 检测到服务端返回的消息,也会通知客户端:“消息返回了,你去取吧“ 。客户端再去获取消息 。整个过程 EventLoop 就是监视器+传声筒 。


推荐阅读