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的数量,以优化性能。
缺点:编程复杂度较高,需要仔细设计和协调各个组件。系统架构相对复杂,维护成本增加。