天天看点

reactor模型_图解Reactor模型

    在BIO线程模型中,为了解决同步阻塞的问题,采用了多线程的方式处理并发,即经典的connection per thread,每一个连接用一个线程处理。虽然在单个线程内仍然是阻塞的,但在整体上看是可以同时处理多个连接请求的,原理图如下:

reactor模型_图解Reactor模型

    但这种方式的缺点在于资源要求太高,系统中创建线程是需要比较高的系统资源的,如果连接数太多,系统无法承受,而且,线程的反复创建和销毁也需要代价。

    为了解决这个问题,出现了Reactor线程模型。简单来说,Reactor线程模型就是多路I/O复用结合线程池的思想。

  • I/O多路复用:多个连接共用一个阻塞对象(即下图中的ServiceHandler),应用程序只需要在一个阻塞对象等待,无需阻塞等待所有连接,当某个连接有新的数据可以处理时,操作系统通知应用程序线程从阻塞状态返回,并将数据分发给对应的线程处理
  • 基于线程池复用线程资源:不必再为每个连接创建线程,将连接完成后的业务处理任务交给线程池中的线程处理,处理完成后归还线程,同一个线程可以处理多个连接的业务,达到线程复用
reactor模型_图解Reactor模型

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

  • 单Reactor单线程
  • 单Reactor多线程
  • 主从Reactor多线程

1.单Reactor单线程模式 (Reactor和handler都在同一个线程中)

方案说明:

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

这种模式的缺点在于:

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

2.单Reactor多线程 方案说明:

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

优点:

  • 多线程可以充分利用多核CPU的处理能力
  • 采用线程池复用线程,减少创建和销毁线程带来的性能开销

缺点:

  • reactor处理所有事件的监听和响应,在单线程运行,高并发场景下容易出现性能瓶颈
  • 多线程数据共享和访问比较复杂

3.主从Reactor多线程

方案说明:

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

优点:

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

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