网络线程模型

传统阻塞 I/O 服务模型

传统阻塞 I/O 服务模型采用阻塞式I/O获取输入的数据,每个连接都需要独立的线程完成数据的输入、业务的处理、以及数据的返回;因此会发生两个问题:(1).当并发数很大时,就会创建大量的线程,占用较大的系统资源;(2).连接创建后,如果当前线程暂时没有数据可读,该线程会阻塞在 Handler对象中的read 操作,导致资源浪费;

传统阻塞 IO 服务模型.jpg

Reactor 模式服务模型

反应器 Reactor模式基于 I/O 复用模型,多个连接共用一个ServiceHandler阻塞对象,程序无需阻塞等待所有连接,这样就减少了阻塞时间;当多个客户端进行连接时,先把连接请求交给ServiceHandlerServiceHandler把请求分派到对应的EventHandler进行处理;Reactor模式根据Reactor 的数量和处理资源池线程的数量不同分为三种实现:单 Reactor 单线程、单 Reactor多线程、主从 Reactor多线程;

Reactor模式.jpg

1.单 Reactor 单线程模型

Reactor 单线程模型实现中Reactor 对象通过 Select 监控客户端请求事件,收到事件后通过 Dispatch 进行分发;若此时有客户端请求:首先判断请求类型;如果是建立连接请求事件,则由 Acceptor 通过 accept 处理连接请求,然后创建一个 Handler 对象处理连接完成后的后续业务处理;如果不是建立连接事件,则 Reactor 会分发调用连接对应的 Handler 来处理(这里的Handler负责事件的响应和业务的处理);这种实现中所有请求的所有操作通过一个线程处理很容易导致性能瓶颈;

单Reactor单线程.jpg

2.单 Reactor 多线程模型

Reactor多线程模型实现中Reactor 对象通过 Select 监控客户端请求事件,收到事件后,通过 Dispatch 进行分发;若此时有客户端请求:首先判断请求类型;如果是建立连接请求事件,则由 Acceptor 通过 accept 处理连接请求,然后创建一个 Handler 对象处理连接完成后的后续业务处理;如果不是建立连接事件,则 Reactor 会分发调用连接对应的 Handler 来处理(这里handler 负责响应事件,不做具体的业务处理),Handler通过 read 读取数据后,会分发给后面的 worker 线程池,worker 线程池会分配独立线程完成真正的业务,并将结果返回给 handler;这种实现中Reactor 在主线程中运行并且承担了所有事件的监听和响应,主线程承担了过多的任务,高并发场景下也容易导致性能瓶颈;

单Reactor多线程.jpg

3.主从 Reactor 多线程模型

主从Reactor多线程模型实现中,Reactor 主线程中的 MainReactor 对象通过 select 监听连接事件;若此时有客户端请求:MainReactor收到事件后就通过 Acceptor 处理连接事件;当 Acceptor 处理连接事件后,MainReactor 会将连接分配给 SubReactor(MainReactorSubReactor是一对多的模型);subreactor 将连接加入到连接队列进行监听,并创建 handler 进行各种事件处理;当有新事件发生时,subreactor 就会调用对应的 handler 处理;handler 通过 read 读取数据,分发给后面的 worker 线程处理;worker 线程池分配独立的 worker 线程进行业务处理,并返回结果,handler 收到响应的结果后,再通过 send 将结果返回给 client

主从Reactor多线程.jpg

Netty Reactor服务模型

Netty 抽象出两组线程池 :BossGroupWorkerGroup,其中BossGroup 专门负责接收客户端的连接,WorkerGroup专门负责网络的读写;BossGroupWorkerGroup中对象的类型都是 NioEventLoopGroupNioEventLoopGroup 相当于一个事件循环组,这个组中含有多个事件循环对象NioEventLoopNioEventLoop 表示一个不断循环的执行处理任务的线程,每个 NioEventLoop 都有一个 Selector,用于监听绑定在其上的 socket 的网络通讯;

每个 BossGroup下面的NioEventLoopGroup 中的NioEventLoop 循环执行的步骤有 3 步:(1)轮询 accept 事件;(2)处理 accept 事件,与 client 建立连接,生成 NioScocketChannel,并将其注册到某个 workerGroupNIOEventLoop 上的 Selector上;(3)继续处理任务队列的任务,即 runAllTasks

每个 WorkerGroup 下面的NioEventLoopGroup 中的NIOEventLoop 循环执行的步骤:(1)轮询 readwrite 事件;(2)处理 I/O 事件,即 readwrite 事件,在对应 NioScocketChannel 处理;(3)处理任务队列的任务,即 runAllTasks

Netty线程模型.jpg

你可能感兴趣的:(网络线程模型)