Netty架构原理深度解析,必学框架!( 三 )


篇幅关系,这里不再具体展开 Reactor 特性、优缺点比较,有兴趣的读者可以参考我之前另外一篇文章:《理解高性能网络模型》 。
Netty 线程模型
Netty 主要基于主从 Reactors 多线程模型(如下图)做了一定的修改,其中主从 Reactor 多线程模型有多个 Reactor:
MainReactor 负责客户端的连接请求,并将请求转交给 SubReactor 。
SubReactor 负责相应通道的 IO 读写请求 。
非 IO 请求(具体逻辑处理)的任务则会直接写入队列,等待 worker threads 进行处理 。
这里引用 Doug Lee 大神的 Reactor 介绍:Scalable IO in Java 里面关于主从 Reactor 多线程模型的图:

Netty架构原理深度解析,必学框架!

文章插图
 
主从 Rreactor 多线程模型
特别说明的是:虽然 Netty 的线程模型基于主从 Reactor 多线程,借用了 MainReactor 和 SubReactor 的结构 。但是实际实现上 SubReactor 和 Worker 线程在同一个线程池中:
EventLoopGroup bossGroup = newNioEventLoopGroup();
EventLoopGroup workerGroup = newNioEventLoopGroup();
ServerBootstrap server= newServerBootstrap();
server.group(bossGroup, workerGroup)
.channel(NIOServerSocketChannel. class)
上面代码中的 bossGroup 和 workerGroup 是 Bootstrap 构造方法中传入的两个对象,这两个 group 均是线程池:
bossGroup 线程池则只是在 Bind 某个端口后,获得其中一个线程作为 MainReactor,专门处理端口的 Accept 事件,每个端口对应一个 Boss 线程 。
workerGroup 线程池会被各个 SubReactor 和 Worker 线程充分利用 。
异步处理
异步的概念和同步相对 。当一个异步过程调用发出后,调用者不能立刻得到结果 。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者 。
Netty 中的 I/O 操作是异步的,包括 Bind、Write、Connect 等操作会简单的返回一个 ChannelFuture 。
调用者并不能立刻获得结果,而是通过 Future-Listener 机制,用户可以方便的主动获取或者通过通知机制获得 IO 操作结果 。
当 Future 对象刚刚创建时,处于非完成状态,调用者可以通过返回的 ChannelFuture 来获取操作执行的状态,注册监听函数来执行完成后的操作 。
常见有如下操作:
通过 isDone 方法来判断当前操作是否完成 。
通过 isSuccess 方法来判断已完成的当前操作是否成功 。
通过 getCause 方法来获取已完成的当前操作失败的原因 。
通过 isCancelled 方法来判断已完成的当前操作是否被取消 。
通过 addListener 方法来注册监听器,当操作已完成(isDone 方法返回完成),将会通知指定的监听器;如果 Future 对象已完成,则理解通知指定的监听器 。
例如下面的代码中绑定端口是异步操作,当绑定操作处理完,将会调用相应的监听器处理逻辑 。
serverBootstrap.bind(port).addListener(future -> {
if(future.isSuccess()) {
System.out. println( newDate() + ": 端口["+ port + "]绑定成功!");
} else{
System.err. println( "端口["+ port + "]绑定失败!");
}
});
相比传统阻塞 I/O,执行 I/O 操作后线程会被阻塞住, 直到操作完成;异步处理的好处是不会造成线程阻塞,线程在 I/O 操作期间可以执行别的程序,在高并发情形下会更稳定和更高的吞吐量 。
Netty 架构设计
前面介绍完 Netty 相关一些理论,下面从功能特性、模块组件、运作过程来介绍 Netty 的架构设计 。
功能特性
Netty架构原理深度解析,必学框架!

文章插图
 
Netty 功能特性如下:
传输服务,支持 BIO 和 NIO 。
容器集成,支持 OSGI、JBossMC、Spring、Guice 容器 。
协议支持,HTTP、Protobuf、二进制、文本、WebSocket 等一系列常见协议都支持 。还支持通过实行编码解码逻辑来实现自定义协议 。
Core 核心,可扩展事件模型、通用通信 API、支持零拷贝的 ByteBuf 缓冲对象 。
模块组件
Bootstrap、ServerBootstrap
Bootstrap 意思是引导,一个 Netty 应用通常由一个 Bootstrap 开始,主要作用是配置整个 Netty 程序,串联各个组件,Netty 中 Bootstrap 类是客户端程序的启动引导类,ServerBootstrap 是服务端启动引导类 。
Future、ChannelFuture
正如前面介绍,在 Netty 中所有的 IO 操作都是异步的,不能立刻得知消息是否被正确处理 。
但是可以过一会等它执行完成或者直接注册一个监听,具体的实现就是通过 Future 和 ChannelFutures,他们可以注册一个监听,当操作执行成功或失败时监听会自动触发注册的监听事件 。


推荐阅读