Reactor模型

解决的问题:

  • NIO-API复杂,开发难度大;

Netty:

  • 是对NIO的API进行封装;
  • 性能高,吞吐量高,延迟低,减少资源消耗,减少不必需要的内存复制;
  • 基于主从Reactor多线程模型

传统阻塞IO架构:

actor架构 reactor架构_多线程

Reactor模型

actor架构 reactor架构_子线程_02

  • ServiceHandler将传入的多个请求,根据事件,分发给相应的处理线程;
  • ServiceHandler:即一个Reactor
  • 基于Dispatcher分发模式;
  • 使用了IO复用监听事件;

分类:

  1. 单Reactor单线程;
  2. 单Reactor多线程;
  3. 主从Reactor多线程;

单Reactor单线程

actor架构 reactor架构_actor架构_03

Reactor,Handler都是同一个线程;(单层架构,性能差)

  • Reactor通过Selecotr.select:监听多路连接请求;
  • 收到连接事件后,通过Acceptror处理连接请求;
  • 收到读写事件,通过Handler处理业务;

单Reactor多线程

actor架构 reactor架构_主线程_04

分为:主线程Reactor,业务处理线程池;(两层架构)

  1. Reactor中Selecotr.select方法,进行轮询;
  2. 连接请求:通过serverSocketChannel.accept()方法建立连接,并创建对应的Handler;
  3. 读写请求:调用此连接对应的Handler进行相应,Handler只负责响应,不做业务处理;
  4. Handler读取事件数据,启动一个独立的Worker线程,进行业务处理,结果返回Handler
  5. Handler收到结果,将响应返回给Client;

优点:充分利用多核CPU,并发处理能力;

缺点:在高并发场景,由于主线程处理所有的连接请求,读写请求,容易出现瓶颈;

主从Reactor多线程

actor架构 reactor架构_主线程_05

这个图不全,这里的SubReactor子线程,是可以有多个的;

在netty中MainReactor也是有多个的;

在单Reactor基础上:(三层架构)

  1. MainReactor:只需要处理连接请求,将读写请求交由子线程SubReactor处理;
  2. 多个Reactor子线程SubReactor:分担了MainReactor的读写请求;
  3. MainReactor建立连接完成的Channle会加入一个连接队列,SubReactor通过Selecotr.select轮询监听连接的事件;
  4. 有读写事件发生时:SubReactor会调用相应的Handler进行处理;
  5. Handler读取数据,从线程池中,调用独立work线程,处理业务,返回结果给Handler;
  6. Handler收到结果,send给Client;

优点:

(1)父线程与子线程的数据交互简单职责明确;

(2)父线程与子线程的数据交互简单,MainReactor主线程只需要把新连接传给子线程,子线程无需返回数据。

缺点:编程复杂度较高;