Netty
Netty一个线程通过多路复用,能够实现多个socket的非阻塞的调用。
Reactor
Reactor 模式是一种设计模式,也叫响应器模式。
以下是 Reactor 模式的基本组成部分:
- 事件处理器(Event Handlers): 这些是实际处理特定类型事件的组件。它们通过注册到 Reactor 中来接收事件通知。
-
事件分发器(Reactor): 这是一个中央调度器,负责监听各种事件并将其分发给相应的事件处理器。Reactor
维护了一个事件处理器的注册表,以及与事件关联的回调函数。
-
事件(Events): 这是在系统中发生的各种动作或状态变化,可能包括网络数据到达、定时器触发、用户输入等。
Reactor 模式的主要优势在于它能够处理大量并发请求而不需要为每个请求创建新的线程。
通过IO多路复用监听事件,收到事件后,根据事件类型分配给线程,Reactor 模式可以在一个单线程或者少数几个线程的情况下处理大量并发请求,提高系统的效率和性能。
Reactor的实现
Reactor 模式主要由 Reactor 和处理资源池这两个核心部分组成,它俩负责的事情如下:
Reactor 负责监听和分发事件,事件类型包含连接事件、读写事件等;
处理资源池负责处理事件,如(读请求事件 -> 处理请求事件 -> 发送响应);
3 个经典方案
- 单 Reactor 单线程;
- 单 Reactor 多线程;
- 多 Reactor 多线程;
单 Reactor 单进程 / 线程
Reactor 对象通过 select (IO 多路复用接口) 监听事件,收到事件后通过 dispatch 进行分发,具体分发给 Acceptor 对象还是 Handler 对象,还要看收到的事件类型:
- 如果是连接建立的事件,则交由 Acceptor 对象进行处理,Acceptor 对象会通过 accept 方法 获取连接,并创建一个 Handler 对象来处理后续的响应事件;
- 如果不是连接建立事件, 则交由当前连接对应的 Handler 对象来进行响应;
单 Reactor 多线程
上面的三个步骤和单 Reactor 单线程方案是一样的,接下来的步骤就开始不一样了:
Handler 对象不再负责业务处理,只负责数据的接收和发送,Handler 对象通过 read 读取到数据后,会将数据发给子线程 里的 Processor 对象进行业务处理;
子线程里的 Processor 对象就进行业务处理,处理完后,将结果发给主线程 中的 Handler 对象,接着由 Handler 通过 send 方法将响应结果发送给 client;
单 Reator 多线程的方案优势在于能够充分利用多核 CPU 的能,那既然引入多线程,那么自然就带来了多线程竞争资源的问题。
例如,子线程完成业务处理后,要把结果传递给主线程的 Reactor 进行发送,这里涉及共享数据的竞争。
要避免多线程由于竞争共享资源而导致数据错乱的问题,就需要在操作共享资源前加上互斥锁,以保证任意时间里只有一个线程在操作共享资源,待该线程操作完释放互斥锁后,其他线程才有机会操作共享数据。
多 Reactor 多线程
主线程中的 MainReactor 对象通过 select 监控连接建立事件,收到事件后通过 Acceptor 对象中的 accept 获取连接,将新的连接分配给某个子线程;
子线程中的 SubReactor 对象将 MainReactor 对象分配的连接加入 select 继续进行监听,并创建一个 Handler 用于处理连接的响应事件。
如果有新的事件发生时,SubReactor 对象会调用当前连接对应的 Handler 对象来进行响应。
Handler 对象通过 read -> 业务处理 -> send 的流程来完成完整的业务流程。
参考CSDN博主「attempt_to_do」
原文链接:https://blog.csdn.net/weixin_43021844/article/details/125045251