网络线程模型经历的阶段
单线程——>多线程——>线程池——>reactor模式
// 单线程模式,无法并发,如果当前的请求没有处理完,那么后面的请求只能被阻塞,服务器的吞吐量太低。
while(true){
socket = accept();
handle(socket);
}
// 多线程模式,每一个连接用一个线程处理。
while(true){
socket = accept();
new Thread(socket);
}
// 线程池模式,减少了线程的反复创建和销毁,但本质上一个线程还是要完整的处理连接、读取、写入
while(true){
socket = accept();
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(new Thread(socket));
}
// reactor模式(基于IO多路复用的技术)
1. java nio的select函数,可以同时监听多个套接字socket。每个socket都会关联连接event、读取event、回写event。
2. 把一个线程拆分成更小的粒度:建立连接的handler、读取数据的handler、回写数据的hander。handler处理完event就丢给下一个handler处理,自己又可以去服务socket,提高了复用率,提高了系统的吞吐量。
Reactor 模式
- 单Reactor单线程
- 单Reactor多线程
- 主从Reactor多线程
单Reactor单线程
适用场景
客户端的数量有限,业务处理非常快速
Select 是标准网络编程 API,可以实现应用程序通过一个阻塞对象监听多路连接请求 ,Reactor 对象通过 Select 监控客户端请求事件,收到事件后通过 Dispatch 进行分发 ,如果是建立连接请求事件,则由 Acceptor 通过 Accept 处理连接请求,然后创建一个 Handler 对象处理连接 完成后的后续业务处理 。如果不是建立连接事件,则 Reactor 会分发调用连接对应的 Handler 来响应 ,Handler 会完成 Read→业务处理→Send 的完整业务流程
单Reactor多线程
Reactor 对象通过 select 监控客户端请求 事件, 收到事件后,通过 dispatch 进行分发,如果建立连接请求, 则右 Acceptor 通过 accept 处理连接请求, 然后创建一个 Handler 对象处理完成连接后的各种事件,如果不是连接请求,则由 reactor 分发调用连接对应的 handler 来处理。handler 只负责响应事件,不做具体的业务处理, 通过 read 读取数据后,会分发给后面的 worker 线程池的某个线程处理业务。 worker 线程池会分配独立线程完成真正的业务,并将结果返回给 handler 。handler 收到响应后,通过 send 将结果返回给 client
主从Reactor多线程
适用场景
Reactor 主线程 MainReactor 对象通过 select 监听连接事件, 收到事件后,通过 Acceptor 处理连接事件 。当 Acceptor 处理连接事件后,MainReactor将连接分配给 SubReactor。subreactor 将连接加入到连接队列进行监听,并创建 handler 进行各种事件处理 。当有新事件发生时, subreactor 就会调用对应的 handler 处理 。handler 通过 read 读取数据,分发给后面的 worker 线程处理 。worker 线程池分配独立的 worker 线程进行业务处理,并返回结果。handler 收到响应的结果后,再通过 send 将结果返回给 client 。Reactor 主线程可以对应多个 Reactor 子线程, 即 MainRecator 可以关联多个 SubReactor
生活理解
- 单 Reactor 单线程,前台接待员和服务员是同一个人,全程为顾客服
- 单 Reactor 多线程,1 个前台接待员,多个服务员,接待员只负责接待