这是我参与8月更文挑战的第16天,活动详情查看: 8月更文挑战
Reactor线程模型并不是⼀种并发编程模型,是⼀种思想,Netty中结合了NIO的特点,也应⽤了Reactor线程模型的思想来实现 Reactor模型中有3个比较重要的角色:
- Reactor:负责监听和分配事件,将I/O事件分派给对应的Handler。新的事件包含连接建⽴就绪、读就绪、写就绪等
- Acceptor:处理客户端新连接,并分派请求到处理器链中
- Handler:将⾃身与事件绑定,执⾏⾮阻塞读/写任务,完成channel的读⼊,完成处理业务逻辑后,负责将结果写出channel
常见的Reactor线程模型有三种:
- Reactor单线程模型
- Reactor多线程模型
- 主从Reactor多线程模型
Reactor单线程模型
该模型中:
- Reactor充当多路复用器的角色,对所有的连接请求进行监听,由单线程完成
- Reactor收到客户端请求后,如果是新连接则扔给Acceptor来完成,其他的请求则由Handler完成
- Handler完成业务逻辑的处理,基本的流程:Read-->业务处理-->Send
这样做的优缺点:
-
优点:
- 结构简单,由单线程完成,没有多线程、进程通信等问题。
- 适合⽤在⼀些业务逻辑⽐较简单、对于性能要求不⾼的应⽤场景
-
缺点:
- 由于是单线程操作,不能够发挥多核服务器的性能
- 当Reactor线程负载过重之后,处理速度将变慢,这会导致⼤量客户端连接超时,超时之后往往会进⾏重发,这更加重Reactor线程的负载,最终会导致⼤量消息积压和处理超时,成为系统的性能瓶颈。
- 可靠性差,如果该线程进⼊死循环或意外终⽌,就会导致整个通信系统不可⽤,容易造成单点故障
Reactor多线程模型
- Reactor多线程模型相比单线程模型来看,不同点就是Handler处理业务的时候,将业务池处理的逻辑交由线程池来完成,这样可有降低Reactor的性能开销,可以充分利用CPU的资源,提升了应用的吞吐量
模型存在的问题:
- 因为业务处理在多线程中处理,对于数据共享和访问比较复杂,如果子线程完成业务处理后, 需要将结果传递给主线程Reactor进行发送,就会涉及到后面的一系列操作比如共享数据的互斥和保护机制等
- 一个Reactor承担了所有的事件,只有一个主Reactor的时候,面对百万客户端连接,就会存在性能问题,毕竟只有一个Reactor忙不过来
主从Reactor多线程模型
主从模型中,将Reactor分成2部分:
- 主Reactor负责监听server socket,⽤来处理⽹络IO连接建⽴操作,将建⽴的socketChannel指定注册给从Reactor
- 从Reactor主要完成和建⽴起来的socket的数据交互和事件业务处理操作
该模型的优点:
- 响应快,不必为单个同步事件所阻塞,虽然Reactor本身依然是同步的
- 可扩展性强,可以⽅便地通过增加SubReactor实例个数来充分利⽤CPU资源
- 可复⽤性⾼,Reactor模型本身与具体事件处理逻辑⽆关,具有很⾼的复⽤性