网络编程基础-Reactor线程模型-原理剖析

1、Reactor基本概念

Reactor线程模型其实是一种设计模式,其核心思想就是将输入多路复用事件派发相结合,从而减少系统中活跃线程的数量。

像我们之前讲到的文章网络编程基础-IO模型深入理解_网络io-CSDN博客提到了其中网络IO模型(BIO、NIO、AIO),那这两者之间有什么关系呢?

①、Reactor模式通常建立在I/O复用的基础上。使用如epoll这样的机制可以让一个线程同时监控大量的socket连接,只有当某个socket上有数据可读/可写时才会被唤醒去处理,从而避免了传统的每个连接一个线程的开销。

②、为了配合Reactor模式下的高效处理流程,通常需要采用非阻塞I/O。这样即使某次读写操作未能立即完成,也不会导致线程阻塞,而是可以让出CPU时间片给其他任务。

③、Reactor线程模型充分利用了现代操作系统提供的高效I/O机制,特别是I/O复用和非阻塞I/O,来提高服务器程序对大规模并发连接的支持能力

所以要理解Reactor线程模型必须就要理解IO多路复用(Buffer、Channel、Selector)

2、Reactor中的三种角色

Acceptor

作用:专门用于处理新连接请求的事件处理器。

职责:通常与服务器端的监听套接字相关联,一旦监听到新的客户端连接请求,Acceptor就会被触发,它负责接受这个新连接,并创建一个新的SocketChannel(或其他形式的连接表示)。之后,Acceptor可以注册这个新连接到Reactor上,以便后续的数据读写事件能够得到处理。

这个可以理解为IO多路复用中与Channel相关的业务,其实就是Accept函数

Reactor

作用:作为事件循环的核心,负责监听多个I/O事件,并将这些事件分发给相应的处理器。

职责:管理一个或多个事件分发器(如epoll),监控一组文件描述符的状态变化。当有事件发生时,Reactor会根据事件类型调用对应的处理器。

这个可以理解为IO多路复用中的Selector

Handler

作用:处理具体业务逻辑的事件处理器。

职责:针对特定类型的事件执行操作,比如读取数据、写入响应等。每个Handler专注于一种类型的事件处理,它可以是读处理器、写处理器或者其他任何类型的处理器。

3、几种Reactor线程模型

1)、单Reactor-单线程模型

结构:

  • 一个Reactor线程负责监听连接请求,并处理所有客户端的I/O事件。
  • 所有的读写操作都在这个单一的线程中完成。

流程:

  • Reactor通过select或其他多路复用机制(epoll)监控多个客户端socket。
  • 当有新的连接请求时,Acceptor处理并接受连接。
  • 连接建立后,Reactor继续监听该连接上的读写事件。
  • 当读写事件发生时,相应的Handler处理这些事件,包括数据的读取、业务逻辑的执行以及结果的发送。

优点:模型简单,易于理解和实现。不涉及线程间的通信,避免了多线程编程中的复杂性。

缺点:所有的处理都依赖于一个线程,无法充分利用多核CPU。如果唯一的工作线程挂起或崩溃,整个系统将无法响应其他客户端。

2)、单Reactor-多线程模型

结构:

  • 一个Reactor线程负责监听和分发事件。
  • 多个工作线程(Worker线程池)负责处理具体的业务逻辑。

流程:

  • Reactor通过select监听客户端连接请求。
  • 新连接由Acceptor处理,并创建一个Handler来处理后续的读写事件。
  • 当读写事件发生时,Reactor将事件分发给对应的Handler。
  • Handler读取数据后,将数据处理任务提交给Worker线程池。
  • Worker线程处理完业务逻辑后,将结果返回给Handler,由Handler将结果发送回客户端。

优点:能够利用多核CPU提高性能。通过线程池分离I/O操作与业务逻辑处理,提高了系统的吞吐量。

缺点:Reactor线程仍然是单线程,高并发情况下可能成为性能瓶颈。线程间的数据共享和同步增加了复杂性。

3)、主从Reactor-多线程模型

结构:

  • 一个主Reactor(MainReactor)负责监听新连接请求。
  • 多个从Reactor(SubReactor)各自管理一部分已建立的连接,并处理这些连接上的读写事件。
  • 每个从Reactor通常有自己的工作线程池来处理具体的业务逻辑。

流程:

  • MainReactor通过select监听新的连接请求。
  • 当有新的连接请求时,Acceptor处理并接受连接,然后将新连接分配给某个SubReactor。
  • SubReactor将连接加入到自己的选择器中进行监听,并为该连接创建Handler。
  • 当连接上有读写事件发生时,SubReactor调用对应的Handler处理事件。
  • Handler读取数据后,将数据处理任务提交给对应的Worker线程池。
  • Worker线程处理完业务逻辑后,将结果返回给Handler,由Handler将结果发送回客户端。

优点:能够更好地扩展,适应更高并发的场景。分离了连接建立和I/O事件处理,使得系统更加灵活和高效。可以根据需要调整MainReactor和SubReactor的数量,以优化性能。

缺点:编程复杂度较高,需要仔细设计和协调各个组件。系统架构相对复杂,维护成本增加。

相关推荐
蟾宫曲1 天前
网络编程 03:端口的定义、分类,端口映射,通过 Java 实现了 IP 和端口的信息获取
java·网络·网络编程·ip·端口
丶Darling.2 天前
进程间通信博客总结目录
linux·网络编程·进程同步·系统编程·c/c++·阻塞和非阻塞
丶Darling.2 天前
linux高性能服务器编程读书笔记目录&&建议
linux·服务器·网络编程·目录·系统编程·c/c++·博客总结
ktkiko114 天前
线性池学习
jvm·线程·线程池·进程
自律的kkk5 天前
网络编程中的黏包和半包问题
java·开发语言·网络·网络编程·tcp·nio
丶Darling.5 天前
高并发服务器实现总结目录
运维·服务器·网络·网络编程·c/c++·阻塞和非阻塞
程序研20 天前
Lock锁的使用
java·开发语言·线程
枫叶丹420 天前
【在Linux世界中追寻伟大的One Piece】多线程(三)
java·linux·开发语言·线程
小丑西瓜66620 天前
线程的互斥与同步
linux·服务器·开发语言·c++·线程·信号量·互斥与同步
沥川同学1 个月前
跨平台应用开发框架(1)----Qt(组件篇)
c++·qt·udp·线程·tcp·qt5·qt6.3