Netty和Reactor模型

0 篇文章 0 订阅
前言

在我们传统的网络模型中,往往是一个线程一个请求,这样可以避免请求因为线程阻塞而得不到处理(前提是机器性能足够),但这种模式,只适用于并发量较小的场景,并发量一大,一个线程一个请求的开销是机器不能承受的。

reactor模式
单线程Reactor

在这里插入图片描述
在该模式下,Reactor单独占一个线程,负责对请求的接受,分发(java nio 中即为selector),java NIO就采用了这种模式。我们来看看具体流程

  • 服务器端的Reactor是一个线程对象,它注册一个acceptor事件处理器到它下面,只有被注册的事件(处理器)才能被Reactor监听到,该事件处理器在
  • 客户端向服务器端发起一个连接请求,Reactor监听到该请求(因为之前注册了acceptor事件处理器),将该请求交给accetpor处理器。
  • acceptor处理器通过acceptor()方法拿到这个客户端对应的连接(SocketChannel),然后将该连接所需要的事件(如Read事件,Write事件)及对应的事件处理器注册到Reactor中,这样以来Reactor也能监听该连接所需的事件了
  • 当连接要发送数据或读取数据时,就会触发对应的事件处理器进行读写.
    我们可以看到Reactor模式明显改善了之前传统网络模型中,线程阻塞的问题,只有在对应Read/write被处罚时,线程才会去读写,其余时间可以干别的事。
  • 事件处理器完成任务后,将结果返回给客户端

但是这种方式缺点也很明显,单线程Reactor模式的I/O和业务逻辑都是一个线程在执行,这就相当于参观员工既要接待客人,又要去厨房烧菜,洗碗,明显不合理。

多线程Reactor模式

为了解决单线程Reactor模式中,一个线程任务过多的问题,多线程的Reactor模式孕育而生。
在这里插入图片描述

与单线程Reactor模式相比,它把非I/O操作给剥离出来,交给一个线程池来处理。这就相当于在一个员工的基础上,又雇了一批专门的厨师,原来的全能员工不用再负责烧饭菜了,但仍旧需要接待客人(监听事件),把饭菜端上桌(IO操作)所以这种多线程Reactor模式也不是很好,毕竟所有请求的IO都压在一个线程上,压力也很大

主从Reactor模式

该模式把单个Reactor变成多个Reactor,但这些Reactor并不是功能完全相同的平行关系,而是按业务划分的主从关系。在该模式下,我们有1个主Reactor多个从Reactor,他们之间的区别如下

  • 主Reactor只有一个,从Reactor是多个
  • 主Reactor只负责监听请求,把请求分发给从Reactor,从Reactor和其下注册的事件处理器负责处理这个请求
  • 所有的IO操作还是在SubReactor完成,线程池仅完成业务逻辑
    在这里插入图片描述
    接下来我们来看看主从Reactor模式的工作流程
  • 注册一个Acceptor事件处理器到mainReactor中
  • 客户端向服务器端发起一个连接请求,mainReactor监听到了该ACCEPT事件并将该ACCEPT事件派发给Acceptor hadnler 来进行处理。Acceptor handler 通过accept()方法得到与这个客户端对应的连接(SocketChannel),然后将这个SocketChannel传递给subReactor线程池。
  • subReactor将连接加入到连接队列并注册到该subReactor下(还有对应的handler)
  • 当对应的handler被触发时,subReactor调用对应的handler进行处理,并把非IO操作交给线程池处理
  • 线程池分配单独的线程处理,完成后返回结果
  • handler收到结果后,返回给客户端
    这种方式以及可以获得一个不错的性能,还是以餐馆做比喻的话,mainReactor就是餐馆前台服务员,只负责接待客人,subReactor相当于端茶送菜的服务员,在厨房和餐厅来回跑,而线程池就是厨房,工作线程就是厨房里的厨师,只需要负责做菜(完成业务逻辑),这样讲够清楚了吧!。

Netty的线程模型就是基于这种模式改进而来

Netty线程模型(建议看一下Netty的基本组件再看)

在这里插入图片描述
Netty把主从Reactor抽象为Boss Reactor组, 和Worker Reactor组,其中,Boss组就是一个NioEventLoopGroup线程池组,里面有多个NioEventLoop,每个NioEventLoop永久占据一个线程,一个Selector和一个Queue,可以说NioEventLoop就是一个 main Reactor。功能上也是如此,只负责接受客户端连接,然后封装成NioSocketChannel。

 workGroup就是原来sub reactor,主要是负责拿到NioSocketChannel后的处理,它里面的结构和Boss Reactor是一样的。它把NioSocketChannel注册到自己的NioEventLoop上进行监听,一旦有事件发生则交给pipline处理
pipline里有多个handler,对请求进行处理,这个处理可能是格式转换,可能是业务逻辑…

Netty处理请求流程:

  • bossGroup监听到ACCEPT事件
  • bossGroup获取到请求的channel,并封装成NioSocketChannel
  • bossGroup把NioSocketChannel交给workGroup。
  • workGroup把NioSocketChannel注册到自己的某一个EventLoop中(理所当然,一个EventLoop中可注册多个channel),并监听
  • workGroup中的EventLoop监听到读/写事件时,由EventLoop中的线程来处理读写部分,其余逻辑则分配一个工作线程,让新分配的工作线程执行pipline中的handler

关于Netty中的组件我有空再继续写8~

参考:
Netty 线程模型
《Netty实战》

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值