Reactor 模型详解:单 Reactor、主从 Reactor 与 Netty 思想

引言

前面讲完 IO 多路复用后,还差最后一步:

"监听到事件之后,到底该怎么组织线程和业务处理逻辑?"

Reactor 模型就是解决这个问题的经典方案。很多高性能网络框架,本质上都在使用它,比如 Netty。

Reactor 的核心思想可以概括为一句话:

"由一个或多个 Reactor 线程负责监听事件,再把事件分发给对应的处理器执行。"

单 Reactor 单线程模型

这是最基础的一种 Reactor 模型。

工作流程如下:

  1. Reactor 线程通过 select 或其他多路复用接口监听事件。
  2. 如果是连接建立事件,就交给 Acceptor 处理。
  3. 如果是读写事件,就分发给对应的 Handler。
  4. Handler 在同一个线程里完成读取、业务处理、发送响应。

优点

  • 模型简单
  • 没有线程切换和锁竞争
  • 容易实现

缺点

  • 所有连接和业务处理都挤在一个线程里
  • 一旦某个处理耗时,整个系统都会被拖慢
  • 无法充分利用多核 CPU

所以它适合连接数不多、业务处理很轻的场景。

单 Reactor 单线程模型示意图如下:

单 Reactor 多线程模型

在这个模型里,Reactor 线程仍然只有一个,但它不再承担具体业务处理,而是把业务逻辑交给工作线程池。

流程通常是:

  1. Reactor 负责监听和分发事件。
  2. Acceptor 负责处理新连接。
  3. Handler 完成基础的读写。
  4. 读取到的数据再交给 Worker 线程池做业务处理。
  5. 业务处理完成后,把结果回传给 Handler 发送给客户端。

优点

  • 能利用多核 CPU 做业务处理
  • 比单线程模型吞吐更高

缺点

  • Reactor 线程仍可能成为瓶颈
  • 多线程共享数据后,复杂度会明显上升

这个模型适合连接监听压力不算特别大,但业务处理相对耗时的场景。

单 Reactor 多线程模型示意图如下:

主从 Reactor 多线程模型

这是实际高并发服务器中更经典的一种结构。

它把"接收连接"和"处理读写事件"分开了。

典型流程

  1. 主 Reactor 线程只负责监听连接建立事件。
  2. 新连接建立后,交给某个从 Reactor。
  3. 从 Reactor 负责监听该连接后续的读写事件。
  4. 连接对应的 Handler 负责数据收发。
  5. 业务逻辑交给 Worker 线程池处理。
  6. 处理结果再回到 Handler 发送给客户端。

优点

  • 主线程职责很清晰,只负责接入连接
  • 子线程专注于连接读写
  • 更容易发挥多核能力
  • 在高并发、大流量场景下更稳定

这也是很多成熟网络框架采用的思路。

主从 Reactor 多线程模型示意图如下:

三种 Reactor 模型怎么选

可以按业务规模来理解:

单 Reactor 单线程

适合:

  • 简单教学 Demo
  • 轻量级服务
  • 低并发场景

单 Reactor 多线程

适合:

  • 中等并发
  • 连接监听压力还好
  • 业务处理较重

主从 Reactor 多线程

适合:

  • 高并发服务器
  • 连接数多
  • 需要充分利用多核 CPU

Netty 为什么使用 Reactor 思想

Netty 并不是简单地"封装了 Socket",它的价值很大一部分来自对高性能网络模型的抽象。

Netty 的思路本质上接近主从 Reactor 多线程模型:

  • Boss 线程组负责接收新连接
  • Worker 线程组负责处理已建立连接上的读写事件
  • 业务逻辑可以继续交给单独线程池

这样做的好处是:

  • 网络事件和业务逻辑分层清晰
  • 支持高并发连接
  • 扩展性更强

Reactor 和前面 IO 多路复用的关系

这两个概念容易被混为一谈,但它们不是同一层面的东西。

可以这样理解:

  • IO 多路复用解决的是"如何高效监听多个连接"
  • Reactor 模型解决的是"监听到事件后,如何组织处理流程和线程模型"

也就是说,Reactor 常常建立在 select、poll、epoll 这类多路复用机制之上。

总结

Reactor 模型的重点不在于名词,而在于职责拆分:

  1. 谁负责接收连接
  2. 谁负责监听读写事件
  3. 谁负责真正业务处理

从单 Reactor 到主从 Reactor,本质上就是不断把职责拆开,让系统更适合高并发场景。

如果你在学习 Netty,这篇内容一定要和前面的 epoll、NIO 一起理解。只有把这三者连起来,才算真正看懂高性能网络服务的底层设计。


如果这篇文章对你有帮助,欢迎继续阅读本系列后续内容。若文中有不准确或需要补充的地方,也欢迎指出。

相关推荐
小羊没烦恼!21 分钟前
T-SQL查询进阶--理解SQL SERVER中的分区表
服务器·开发语言·前端·javascript·html
小蒜学长24 分钟前
微信小程序-高校自习室管理系统(代码+数据库+LW)
java·spring boot·后端·微信小程序·自习室管理
鸥梨菌Honevid37 分钟前
UVM 中 REQ 和 RSP 类型详解:从通信模型到 item_done 与 put_response
java·前端·servlet
爱吃香菜的初学者37 分钟前
十六.Linux——多线程(2)
linux·运维·开发语言
mmsx40 分钟前
Android 插件化架构:40 个 Gradle 模块的拆分、通信与共存
android·kotlin
mmsx41 分钟前
Android 不改一行源码:用 AspectJ 做三类拦截
android·kotlin
TST-魚爷44 分钟前
易视讯会议摄像头 + 全向麦克风实操讲解稿
android·电脑·钉钉·腾讯会议·zoom会议
瑞克-桑切斯1 小时前
真实企业场景 运维安全与管理
java·网络·github
jeo陽1 小时前
04-循环实战:素数、最大公约数、级数求和与枚举法
c语言·开发语言·数据结构
老板一杯拿铁1 小时前
Java 八股文面试详解:从基础到进阶的全面梳理
java·面试