高性能IO 之Reactor模式

提到高性能IO总离不开Reactor模式。大家会很容易想到Netty、Redis等…它们都是高性能IO的代表作。

最原始的网络编程思路就是服务器用一个while循环,不断监听端口是否有新的套接字连接,如果有,那么就用一个函数去处理。这样做的最大问题就是无法支持高并发,效率低。因为,如果当前的请求没有处理完。那么后面的请求就只能被阻塞。服务器的推图量太低

threadalone

既然单线程限制了吞吐量,那么使用多线程会如何呢?tomcat服务器早期版本就是这样实现的。

多线程

  • 优点
    • 提高吞吐量。线程之间互不影响
  • 缺点
    • 资源消耗严重 :创建、销毁、连接数…
    • 线程池:线程不够也会导致阻塞
    • 由于所有操作都在一个线程中,粒度比较大

threadpool

Reactor事件模型

  • 优点

    • 线程粒度更小,任务单一
    • 每个线程对应不同的handler
    • 每种handler处理一种event
    • 全局selector管理
  • 缺点

    • 连接池增加

Reactor演进过程

reactor1

这种模型由于IO在阻塞时会一直等待,因此在用户负载增加时,性能下降非常快。

导致阻塞的原因

  • serversocket 的accept方法,阻塞等待client连接,直到client连接成功
  • 线程从socket inputstream 读入数据,会进入阻塞状态,直到数据全部读取完
  • 线程向socet outputstream 写入数据,会阻塞直到全部数据写完

改进:基于事件驱动设计,当有触发事件时,才会调用处理器进行数据处理

reactor2

  • Reactor 负责响应IO事件,当检测到一个新的事件,将其发送给相应的Handler去处理
  • Handler负责处理非阻塞的行为,标识系统管理的资源,同时将handler与事件绑定
  • Accept为单个线程,需要处理accept链接。同时发送请求到处理器中

由于Accept是单个线程所以要求处理器的速度要很快

reactor3

  • 将处理器放入线程池,多线程进行业务处理。但Reactor扔为单个线程

多CPU充分利用资源

reactor4

mainReactor负责监听链接,accept链接给subReactor处理。单独分配一个reactor处理监听的理由很简单,因为TCP需要3次握手才能建立连接。这个建立连接的过程也是需要耗时间和资源的,单独分一个reactor来处理可以提高性能。

Reactor模式的优缺点

优点

  • 响应快。不必为单个同步时间阻塞,虽然Reactor本身依然是同步的。
  • 编程相对简单,可以最大程度的避免复杂的多线程及同步问题。避免了多线程/进程的切换开销
  • 可扩展性。可以方便的通过增加Reactor实例个数来充分利用CPU资源
  • 可复用性,Reactor框架本身与具体事件处理逻辑无关,具有很高的复用性

缺点

  • 模型复杂,有一定的门槛,不易于调试
  • 需要底层的Synchronous Event Demultiplexer 支持 比如 java的selector
  • 耗时处理会影响其它操作。比如大文件处理
文档更新时间: 2018-12-14 10:59   作者:杭州-昆仑