Netty学习之Netty模型和Reactor模式

前言

所谓Netty框架,无非就是一种事件处理的方式。那么,在了解Netty框架前,我们需要介绍下用来进行事件处理的线程模型。

线程模型

数据报如何进行读取,读取后的编解码该在哪个线程中运行,编解码得到的信息该如何分发,这都需要依赖于线程模型,不同的线程模型,对事件处理的性能也有很大不同。

事件处理一般有两种思路:
1.轮询方式:通过对事件源不断的轮询访问,来获知实践并调用相关处理逻辑进行处理。
2.事件驱动方式:当发生事件时,将事件源放入队列中或容器中,通过监听器接收通知的对象,再调用相应的事件处理程序进行逻辑处理。

例子:
去餐厅吃饭,发现暂时没位置:
1.轮询方式:每过一段时间,就返回餐厅看看是否有空位。
2.事件驱动:给服务员留下号码,通过服务员来监听是否有空位,一旦有空位就打电话让你来。

这里借用 O’Reilly 大神关于事件驱动模型解释图:
在这里插入图片描述
那么有人要问了,这和Netty有什么关系呢?
先不急,接着往下看,接下来我们要介绍的Reactor三种模型就是基于该事件驱动模型的变形。

Reactor模型

Reactor 是反应堆的意思,Reactor 模式也叫 Dispatcher 模式,即 I/O 多了复用统一监听事件,收到事件后分发(Dispatch 给某进程),是编写高性能网络服务器的必备技术之一。

Reactor 模型中有 2 个关键组成:

1)Reactor:Reactor 在一个单独的线程中运行,负责监听和分发事件,分发给适当的处理程序来对 IO 事件做出反应。它就像公司的电话接线员,它接听来自客户的电话并将线路转移到适当的联系人;

2)Handlers:处理程序执行 I/O 事件要完成的实际事件,类似于客户想要与之交谈的公司中的实际官员。Reactor 通过调度适当的处理程序来响应 I/O 事件,处理程序执行非阻塞操作。

Reactor模型又可以细分为以下三种模型:

1. 单Reactor单线程模型

Reactor单线程模型,指的是所有的I/O操作都在同一个NIO线程上面完成,

Reactor线程负责多路分离套接字,使用Acceptor建立新连接,并分派请求到处理器链中。该模型适用于处理器链中业务处理组件能快速完成的场景。所有操作都只用一个线程。

不过,这种单线程模型不能充分利用多核资源,所以实际使用的不多。
在这里插入图片描述

2. 单Reactor多线程模型

单Reactor多线程通过使用一个专门的NIO线程–acceptor线程用于监听服务端。
而接收客户端的TCP连接请求并且处理请求的Handler使用多线程进行管理,分发到线程池中,更好的利用多核CPU的优势,提升性能。

但由于还是只是使用单个Reactor,所以在高并发的场景中还是会有性能瓶颈。
在这里插入图片描述

3. 主从Reactor多线程模型

主从Reactor多线程服务端用于接收客户端连接的不再是1个单独的NIO线程,而是一个独立的NIO线程池。Acceptor接收到客户端TCP连接请求处理完成后(可能包含接入认证等),将新创建的SocketChannel注册到I/O线程池(sub reactor线程池)的某个I/O线程上,由它负责SocketChannel的读写和编解码工作。

主从 Reactor 多线程模型有多个 Reactor:
1)MainReactor 负责客户端的连接请求,并将请求转交给 SubReactor;

2)SubReactor 负责相应通道的 IO 读写请求;

3)非 IO 请求(具体逻辑处理)的任务则会直接写入队列,等待 worker threads 进行处理。

这里引用 Doug Lee 大神的 Reactor 介绍——Scalable IO in Java 里面关于主从 Reactor 多线程模型的图:
在这里插入图片描述
特别说明的是:虽然 Netty 的线程模型基于主从 Reactor 多线程,借用了 MainReactor 和 SubReactor 的结构。但是实际实现上 SubReactor 和 Worker 线程在同一个线程池中。

上图简化如下:

实际上就是通过一个MainReactor来负责连接和分发,通过SubReactor来调用Handler来进行读写操作。非IO操作则直接放入worker中处理。
在这里插入图片描述

稍微了解过Netty模型的大神们,看到这里有没有觉得很熟悉呢?是的,这就是Netty模型的最初思路来源,而Netty框架也是基于多Reactor多线程模型进行设计的,只是做了些小改动,Netty框架图如下:
在这里插入图片描述
其实这里的Boss Group就相当于MainReactor,而Worker Group就相当于SubReactor。

好啦,关于Netty框架的由来以及大致结构先介绍到这里,而关于Netty框架中的不同模块组件的具体功能(例如NioEventLoop,ChannelHandler),请移步该博客:
Netty学习之模块组件
https://blog.csdn.net/weixin_43896829/article/details/114600287

主从Reactor多线程优缺点

优点:
父线程和子线程的数据交互简单职责明确,父线程只需要接收新连接,子线程完成后续的业务处理。
父线程和子线程的数据交互简单,Reactor主线程只需要把新连接传递给子线程,子线程无需返回数据。

缺点:
要求编程能力更高。

而Netty框架,便是基于主从Reactor多线程。

猜你喜欢

转载自blog.csdn.net/weixin_43896829/article/details/110506011