Reactor 模型 和 Proactor 模型

在网络IO设计中,有两种高性能模型:Reactor模型和Proactor模型。

Reactor基于同步IO模式,Proactor基于异步IO模式。

不过,无论是 Reactor,还是 Proactor,都是一种基于「事件分发」的网络编程模式,区别在于 Reactor 模式是基于「待完成」的 I/O 事件,而 Proactor 模式则是基于「已完成」的 I/O 事件。

一、Reactor

Reactor模型主要就是监听事件分发事件处理事件。其中Reactor角色会负责监听事件 和分发事件Handler角色和Acceptor角色会负责处理事件

Netty网络框架,Redis等中间件中都有使用到Reactor模型。

1.单 Reactor 单线程(Redis使用)

 Java 语言实现的是「单 Reactor 单线程」的方案,因为 Java 程序是跑在 Java 虚拟机这个进程上面的,虚拟机中有很多线程,我们写的 Java 程序只是其中的一个线程而已。

优点

  • 将所有处理逻辑放在一个线程中实现,没有多线程通信、竞争的问题。

缺点

  • 一个 Reactor 既要负责处理连接请求,又要负责处理读写请求,在面对瞬间高并发的场景时,容易成为性能的瓶颈的地方
  • 一旦 Reactor 线程意外中断或者进入死循环,会导致整个系统通信模块不可用。
  • 只有一个线程在工作,处理效率低,无法利用多核CPU的优势。
  • Handler 对象在业务处理时,整个线程是无法处理其他连接的事件的。

2.单 Reactor 多线程

优点

  • 多线程模式可以充分利用 多核CPU 的性能。

缺点

  • 单 Reactor 存在两个的问题(同上)。
  • Handler 使用多线程模式,自然带来了多线程竞争资源的开销,同时涉及共享数据的互斥和保护机制,实现比较复杂。(例如,子线程完成业务处理后,要把结果传递给主线程的 Handler 进行发送,这里涉及共享数据的竞争)

3.主从 Reactor 多线程(Netty使用)

思考:为什么一个Reactor同时监听连接事件和处理读写事件是不好的?

  1. 一般来说处理连接请求是很快的,但处理读写请求时涉及到业务逻辑处理,相对慢很多。所以 Reactor 在处理读写请求时,其他请求只能等着,容易造成系统的性能瓶颈。
  2. 客户端连接的建立是不频繁的,但是连接建立后数据的收发是频繁的,所以如果能够将处理读写事件这个动作拆分出来,让多个子Reactor处理读写事件,而原来的主Reactor只监听连接事件,那么整体的效率,会进一步提升,而这,就是主从Reactor多线程模型。

主线程中的 MainReactor 对象通过 select 监控连接建立事件,收到事件后通过 Acceptor 对象中的 accept 获取连接,将新的连接分配给某个子线程;

子线程中的 SubReactor 对象将 MainReactor 对象分配的连接加入 select 继续进行监听,并创建一个 Handler 用于处理连接的响应事件。

优点

  • 主线程和子线程分工明确,主线程只负责接收新连接,子线程负责完成后续的业务处理。
  • 主线程和子线程的交互也很简单,子线程接收主线程的连接后,只管业务处理即可,无须关注主线程,可以直接在子线程将处理结果发送给客户端。
  • 适用于高并发场景。

二、Proactor

关于同步与异步的概念,大家可以看这篇:

最清楚的 BIO、NIO、AIO 详解!-CSDN博客

现在我们再来理解 Reactor 和 Proactor 的区别,就比较清晰了。

  • Reactor 是非阻塞同步网络模式,感知的是就绪可读写事件。在每次感知到有事件发生(比如可读就绪事件)后,就需要应用进程主动调用 read 方法来完成数据的读取,也就是要应用进程主动将 socket 接收缓存中的数据读到应用进程内存中,这个过程是同步的,读取完数据后应用进程才能处理数据
  • Proactor 是异步网络模式, 感知的是已完成的读写事件。在发起异步读写请求时,需要传入数据缓冲区的地址(用来存放结果数据)等信息,这样系统内核才可以自动帮我们把数据的读写工作完成,这里的读写工作全程由操作系统来做,并不需要像 Reactor 那样还需要应用进程主动发起 read/write 来读写数据,操作系统完成读写工作后,就会通知应用进程直接处理数据

因此,Reactor 可以理解为「来了事件操作系统通知应用进程,让应用进程来处理」,而 Proactor 可以理解为「来了事件操作系统来处理,处理完再通知应用进程」。这里的「事件」就是有新连接、有数据可读、有数据可写的这些 I/O 事件这里的「处理」包含从驱动读取到内核以及从内核读取到用户空间。

无论是 Reactor,还是 Proactor,都是一种基于「事件分发」的网络编程模式,区别在于 Reactor 模式是基于「待完成」的 I/O 事件,而 Proactor 模式则是基于「已完成」的 I/O 事件

介绍一下 Proactor 模式的工作流程:

  • Proactor Initiator 负责创建 Proactor 和 Handler 对象,并将 Proactor 和 Handler 都通过 Asynchronous Operation Processor 注册到内核;
  • Asynchronous Operation Processor 负责处理注册请求,并处理 I/O 操作;
  • Asynchronous Operation Processor 完成 I/O 操作后通知 Proactor;
  • Proactor 根据不同的事件类型回调不同的 Handler 进行业务处理;
  • Handler 完成业务处理;

三、参考

9.3 高性能网络模式:Reactor 和 Proactor | 小林coding (xiaolincoding.com)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值