Loading

Reactor IO模型

Reactor的中心思想是将所有要处理的I/O事件注册到一个中心I/O多路复用器上,同时主线程/进程阻塞在多路复用器上;一旦有I/O事件到来或是准备就绪,多路复用器返回,并将事先注册的相应I/O事件分发到对应的处理器中

相关概念介绍:

  • 事件:就是状态;比如:读就绪事件指的是我们可以从内核读取数据的状态
  • 事件分离器:一般会把事件的等待发生交给epoll、select;而事件的到来是随机,异步的,所以需要循环调用epoll,在框架里对应封装起来的模块就是事件分离器(简单理解为对epoll封装)
  • 事件处理器:事件发生后需要进程或线程去处理,这个处理者就是事件处理器,一般和事件分离器是不同的线程

Reactor的一般流程

  • 1)应用程序在事件分离器注册读写就绪事件读写就绪事件处理器
  • 2)事件分离器等待读写就绪事件发生
  • 3)读写就绪事件发生,激活事件分离器,分离器调用读写就绪事件处理器
  • 4)事件处理器先从内核把数据读取到用户空间,然后再处理数据

 

在Reactor线程模型的发展过程中,出现了不同的实现方式,具体有:

  • 单Reactor单线程

  • 单Reactor多线程

  • 主从Reactor多线程

 

单Reactor 单线程 (Reactor和handler都在同一个线程中)

方案说明:

  • Select是IO复用模型介绍的标准网络编程API,可以实现应用程序通过一个阻塞对象监听多路连接请求
  • Reactor对象通过Select监控客户端请求事件,收到事件后通过Dispatch进行分发
  • 如果是建立连接请求事件,则由Acceptor通过Accept处理连接请求,然后创建一个Handler对象处理连接完成后的后续业务
  • 如果不是建立连接事件,则Reactor会分发调用连接对应的Handler来处理业务
  • Handler会完成Read->业务处理->Send的完整业务流程


c2bcdddaedfdcd364a71e1cb8d43eeb8.png

这种模式的缺点在于:

  • 服务器端用一个线程通过多路复用搞定所有的IO操作,包括连接、读、写等,但是如果客户端连接数较多,将无法支撑,比如处理一个客户端的业务时,别的客户端的业务请求只能阻塞等待
  • 单线程无法发挥多核CPU的性能

 

单Reactor + 多线程

方案说明:

  • Reactor对象通过select监控客户端请求事件,收到事件后,通过dispatcher进行分发
  • 如果是建立连接的请求,则由Acceptor通过accept处理连接请求,然后创建一个Handler对象处理完成连接后的各种事件
  • 如果不是连接请求,则由Reactor分发调用连接对应的handler进行处理
  • handler只负责响应事件,不做具体的业务处理,通过read读取数据后,会分发给后面的worker线程池的某个线程处理业务
  • worker线程池会分发独立的线程完成真正的业务,并将结果返回给handler
  • handler收到响应的结果后,再通过send将结果返回给client


03f594066eb6ecffeace5b2e299e16e6.png

优点:

  • 多线程可以充分利用多核CPU的处理能力

  • 采用线程池复用线程,减少创建和销毁线程带来的性能开销

缺点:

  • reactor处理所有事件的监听和响应,在单线程运行,高并发场景下容易出现性能瓶颈

  • 多线程数据共享和访问比较复杂

 

主从Reactor + 多线程

方案说明:

  • Reactor主线程MainReactor对象通过select监听连接事件,收到事件后,通过Acceptor处理连接事件
  • 当Acceptor处理连接事件后,MainReactor将连接分配给SubReactor
  • SubReactor将连接加入到连接队列进行监听,并创建handler进行各种事件处理
  • 当有新事件发生时,SubReactor就会调用对应的handler进行处理
  • handler通过Read读取数据,分发给后面的worker线程处理
  • worker线程池会分配独立的worker线程进行业务处理,并返回结果
  • handler收到响应的结果后,再通过send将结果返回给client
  • MainReactor主线程可以关联多个SubReactor子线程


cda6b4b4126a944d0e5690b980479b66.png

 

优点:

  • 主线程与子线程的数据交互简单职责明确,主线程只需要接收新连接,子线程完成后续的业务处理
  • 可以通过扩展多个Reactor子线程的方式来减小单个子线程的压力,提高并发处理能力

 

Netty就是在主从Reactor多线程模型的基础上进行了一定的改进,同时,Kafka的网络架构设计也采用了这种主从Reactor多线程的模型。

 

作者:潜行前行
链接:https://juejin.cn/post/6892687008552976398
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

posted @ 2021-08-11 15:21  街头诗人  阅读(73)  评论(0编辑  收藏  举报