问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Reactor模型和Proactor模型详解

创作时间:
作者:
@小白创作中心

Reactor模型和Proactor模型详解

引用
CSDN
1.
https://m.blog.csdn.net/weixin_68074170/article/details/140724998

在网络IO设计中,Reactor模型和Proactor模型是两种重要的高性能模型。它们都基于事件分发机制,但处理IO事件的方式有所不同。本文将详细介绍这两种模型的工作原理、应用场景以及它们之间的区别。

一、Reactor模型

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

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

Java语言实现的是「单Reactor单线程」的方案。由于Java程序运行在Java虚拟机中,虚拟机中有多个线程,而我们写的Java程序只是其中一个线程。

优点

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

缺点

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

2. 单Reactor多线程

优点

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

缺点

  • 单Reactor存在两个问题(同上)。
  • Handler使用多线程模式会带来多线程竞争资源的开销,实现复杂。

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

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

  1. 处理读写请求时涉及业务逻辑处理,相对慢很多,容易造成性能瓶颈。
  2. 客户端连接建立不频繁,但数据收发频繁。如果将处理读写事件拆分给多个子Reactor,主Reactor只负责监听连接事件,整体效率会提升。

工作流程

  • 主线程中的MainReactor对象通过select监控连接建立事件,收到事件后通过Acceptor对象的accept获取连接,分配给某个子线程;
  • 子线程中的SubReactor对象将MainReactor对象分配的连接加入select继续监听,并创建Handler处理连接的响应事件。

优点

  • 主线程和子线程分工明确,主线程只负责接收新连接,子线程负责业务处理。
  • 交互简单,子线程接收连接后只管业务处理,无须关注主线程。
  • 适用于高并发场景。

二、Proactor模型

关于同步与异步的概念,可以参考相关资料。

  • Reactor是非阻塞同步网络模式,感知的是就绪可读写事件。在每次感知到有事件发生(比如可读就绪事件)后,需要应用进程主动调用read方法来完成数据读取,这个过程是同步的。
  • Proactor是异步网络模式,感知的是已完成的读写事件。在发起异步读写请求时,需要传入数据缓冲区的地址等信息,操作系统会自动完成数据读写工作,操作系统完成读写工作后,会通知应用进程直接处理数据。

因此,Reactor可以理解为「来了事件操作系统通知应用进程,让应用进程来处理」,而Proactor可以理解为「来了事件操作系统来处理,处理完再通知应用进程」。

工作流程

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

三、总结

无论是Reactor还是Proactor,都是基于事件分发的网络编程模式,区别在于Reactor模式基于「待完成」的I/O事件,而Proactor模式基于「已完成」的I/O事件。选择哪种模型取决于具体的应用场景和性能需求。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号