Reactor(也叫Dispacher)线程模型不再为每个请求创建线程 ,而是基于 I/O 复用模型,多个请求连接同一个阻塞对象,应用程序只需要在一个阻塞对象等待,无需阻塞等待所有连接。当请求中有数据,操作系统通知应用程序,线程从阻塞状态返回,开始进行业务处理,一个线程可以处理多个连接的业务,如图:
先来理解两个概念
-
Reactor:即图中的ServiceHandler,Reactor负责监听和事件分发,分发给适当的处理程序来对 IO 事件做出反应, 在单独的线程中执行。就像公司的电话接线员,它接听来自客户的电话并将线路转移到适当的联系人;
-
Handlers:Reactor监听到IO事件,需要调度应用程序来处理即:Handler,Handler是真正处理 I/O 事件的程序,类似于接电话的实际的人员。
简单理解就是Reactor线程模型有两个角色 ,一个负责接待请求(Reactor), 一个负责处理请求(Handlers)
Reactor单线程
另外Reactor有三种模式 :Reactor 单线程模型 、单 Reactor 多线程模型 、
Reactor主从多线程模型 。Netty框架是基于主从Reactor多线程模型进行改进(多个主Reactor)。 下面是Reactor单线程模型,如图:
Reactor单线程模型工作流程如下
-
Reactor 通过 Select 监控客户端请求,收到事件后通过 Dispatch 进行请求分发
-
如果是请求事件是建立连接,则由 Acceptor 通过 accept 处理连接请求,然后创建一个 Handler 。
-
如果不是连接事件,则 Reactor 会分发调用连接对应的 Handler 来处理请求
-
Handler 会完成数据read,进行业务处理最后通过 Send 将响应结果返回给 Client
Reactor单线程模型优点是模型简单,缺点也是比较明显
-
线程单一,如果并发高,业务处理慢,很容易导致性能瓶颈,
-
如果线程故障或终止,整个系统不可用
所以这种模型不太适合高并发场景,和业务处理比较耗时的场景。
Reactor多线程
接下来看一下单Reactor 多线程模型 ,先看图把:
Reactor多线程模式工作流程如下
-
Reactor 通过 Select 监控客户端请求,收到事件后通过 Dispatch 进行请求分发
-
如果是请求事件是建立连接,则由 Acceptor 通过 accept 处理连接请求,然后创建一个 Handler 。
-
如果不是连接事件,则 Reactor 会分发调用连接对应的 Handler 来处理请求
-
Handler 只负责响应事件,不做具体业务处理,通过 Read 读取数据后,会分发给后面的 Worker 线程池进行业务处理
-
Worker 线程池会分配独立的线程完成真正的业务处理,将响应结果发给 Handler 进行处理。
-
Handler 收到响应结果后通过 Send 将响应结果返回给 Client。
这种模型引入了线程池,Reactor线程负责接收连接和响应事件,具体IO事件交给线程池分配的线程处理。优点是可以充分利用CPU,提供整体性能,但是Reactor承担所有的事件监听和分发,容易成为性能瓶颈,多线程的数据共享也是一个问题。
主从Reactor多线程
单Reactor多线程的问题是Reactor在单线程中执行可能会成为瓶颈,那么主从Reactor多线程就解决了这个问题 ,看图:
主从Reactor多线程模式工作流程如下
-
Reactor 主线程 MainReactor 对象通过 Select 监听连接事件,收到事件后通过 Acceptor 接收,处理建立连接事件。
-
Acceptor 处理建立连接事件后,MainReactor 将连接分配 Reactor 子线程给 SubReactor 进行处理。
-
SubReactor 将连接加入连接队列进行监听,并创建一个 Handler 用于处理各种连接事件,
-
当有新的事件发生时,SubReactor 会调用连接对应的 Handler 处理
-
Handler 通过 Read 读取数据后,会分发给后面的 Worker 线程池进行业务处理
-
Worker 线程池会分配独立的线程完成真正的业务处理,将响应结果发给 Handler 进行处理
-
Handler 收到响应结果后通过 Send 将响应结果返回给 Client
这种模式的优点比较明显,Reactor主线程只需要接收新连接,子线程完成后续的业务处理,Reactor的压力得到了分担。这种模型在许多项目中广泛使用,包括 Nginx 主从 Reactor 多进程模型,Memcached 主从多线程,Netty 主从多线程模型的支持。
========================================================================
Netty是基于主从Reactor多线程模型实现,Netty的所有IO操作都是异步非阻塞的,通过Future-Listener机制,用户可以方便的主动获取或者通过通知机制获得IO操作结果,Netty线程模型如下图:
Netty线程模型中有两个Group,分别是Boss Group和Worker Group,的BossGroup 用于Accetpt连接建立事件并分发请求,workerGroup用于处理I/O读写事件和业务逻辑。其中关键组件如下
- Channel
Netty网络通信的组件,能够用于执行网络IO操作。
- Selector
Netty基于Selector对象实现I/O多路复用,即:一个线程可以监听多个连接的Channel事件, 当channel向Selector注册 后,Selector 就可以自动不断地查询(select) 注册的Channel是否有已就绪的I/O事件(例如可读, 可写, 网络连接完成等)。
- NioEventLoop
NioEventLoop表示一个不断循环的执行处理任务的线程, 每个NioEventLoop 都有一个 selector。用于监听注册的Channel的IO事件。
NioEventLoop中维护一个线程和任务队列,支持异步提交任务,线程启动时会调用NioEventLoop的run方法,执行IO和非IO任务。 其中IO任务由prossSelectedKeys触发,非IO任务由runAlltasks触发。
- NioEventLoopGroup
NioEventLoopGroup用来管理EventLoop,可以理解为线程组,内部维护了一组线程
Netty线程模型工作流程如下:
-
Boss Group里面的NioEventLoop会轮询accept事件,遇到有新的连接,就生成NioSocketChannel,并把这个Channel注册到Worker Group的Selector上
-
Worker Group轮询read和write事件,在可读或者可写条件满足时,就进行处理
Worker Group和Boss Group都是通过里面的NioEventLoop来操作的。NioEventLoop中维护了一个线程和任务队列,支持异步提交执行任务,线程启动时会调用NioEventLoop的run方法
每个Boss NioEventLoop循环执行的步骤有3步
-
轮询检查accept事件
-
处理accept事件,与client建立连接, 生成NioSocketChannel, 并将其注册到某个 Worker NIOEventLoop上的 selector ,这样Channel的IO事件就交给WorkGroup去监听了。
-
最后执行一个runAllTasks方法,用于处理任务队列中的任务
每个 Worker NIOEventLoop 循环执行的步骤:
-
轮询read, write 事件
-
处理 I/O 事件, 即 read, write 事件, 再对应NioSocketChannel 处理
-
最后执行一个runAllTasks方法,用于处理任务队列中的任务
总结
本篇文件的内容主要介绍了一下Netty,以及三种 Reactor 线程模型,以及Netty的线程模型,Netty的线程模型主要是基于主从Reactor多线程模型升级,在下一章节我们来实战Netty。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
最后
面试前一定少不了刷题,为了方便大家复习,我分享一波个人整理的面试大全宝典
- Java核心知识整理
Java核心知识
- Spring全家桶(实战系列)
- 其他电子书资料
Step3:刷题
既然是要面试,那么就少不了刷题,实际上春节回家后,哪儿也去不了,我自己是刷了不少面试题的,所以在面试过程中才能够做到心中有数,基本上会清楚面试过程中会问到哪些知识点,高频题又有哪些,所以刷题是面试前期准备过程中非常重要的一点。
以下是我私藏的面试题库:
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
面试题的,所以在面试过程中才能够做到心中有数,基本上会清楚面试过程中会问到哪些知识点,高频题又有哪些,所以刷题是面试前期准备过程中非常重要的一点。
以下是我私藏的面试题库:
[外链图片转存中…(img-vFs4Qe7W-1713445485691)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!