Netty线程模型

Netty线程模型

前言

接着我们学习一下 Netty 的线程模型,了解了 Netty 的线程模型之后我们对 Netty 的整体架构也就有了一个大致的了解。

由于 Netty 的线程模型是基于 Reactor 模型改进而来的,因此先讲讲 Reactor 模型,有助于我们对 Netty 线程模型的理解 。

一、Reactor 模型

The reactor design pattern is an event handling pattern for handling service requests delivered concurrently to a service handler by one or more inputs. The service handler then demultiplexes the incoming requests and dispatches them synchronously to the associated request handlers.

Reactor 模式也叫做反应器设计模式,是一种为处理服务请求并发提交到一个或者多个服务处理器的事件设计模式

Reactor 模型是指当服务器接收到多个请求时,服务器程序会把它们分派到不同的方法或线程去处理。Reactor 模式也被称作 Dispatcher 模式。它的核心是多路复用器,多路复用器收到事件后会进行分发,这点是网络服务器高并发的关键。

三种角色:

  1. Reactor:派发器,负责监听和分配事件,并将事件分派给对应的 Handler。新的事件包含连接建立就绪、读就绪、写就绪等。
  2. Acceptor:请求连接器,处理客户端新连接。Reactor 接收到 client 端的连接事件后,会将其转发给 Acceptor,由 Acceptor 接收 Client 的连接,创建对应的 Handler,并向 Reactor 注册此 Handler。
  3. Handler:请求处理器,负责事件的处理,将自身与事件绑定,执行非阻塞读/写任务,完成 channel 的读入,完成处理业务逻辑后,负责将结果写出 channel。可用资源池来管理。

Reactor 模型分为四种:

  • 单 Reactor 单线程
  • 单 Reactor 多线程
  • (主从)多Reactor单线程
  • (主从)多 Reactor 多线程

这三种模型按顺序来看理解起来复杂度不断提升,也会更接近 Netty 的线程模型,下面来分别看看这三种模型。

1.1 单 Reactor 单线程

这个最好理解,只有一个线程,只是会把建立连接和处理请求这两种任务分发给不同的类去处理,如下图所示:

02.Netty线程模型01.png

  1. Reactor 线程通过 select 监听事件,收到事件后通过 Dispatch 进行分发
  2. 如果是连接建立事件,则将事件分发给 Acceptor,Acceptor 会通过 accept() 方法获取连接,并创建一个Handler 对象来处理后续的响应事件
  3. 如果是IO读写事件,则 Reactor 会将该事件交由当前连接的 Handler 来处理
  4. Handler 会完成 read -> 业务处理 -> send 的完整业务流程

优点

  • 模型简单,不会有多线程的那些问题

缺点

  • 性能问题:单线程无法发挥多核 CPU 的性能
  • 可靠性问题:处理业务时往往容易出问题,当 Handler 出问题了,由于只有一个线程,整个节点也挂了
1.2 单 Reactor 多线程

这个线程模型针对前面的问题作出了一定的优化,多出了处理业务的线程池,如下图所示:

02.Netty线程模型02.png

  1. Reactor 线程通过 select 监听事件,收到事件后通过 Dispatch 进行分发
  2. 如果是连接建立事件,则将事件分发给 Acceptor,Acceptor 会通过 accept() 方法获取连接,并创建一个Handler 对象来处理后续的响应事件
  3. 如果是IO读写事件,则 Reactor 会将该事件交由当前连接对应的 Handler 来处理
  4. 与单Reactor单线程不同的是,Handler 不再做具体业务处理,只负责接收和响应事件,通过 read 接收数据后,将数据发送给后面的 Worker 线程池进行业务处理。
  5. Worker 线程池再分配线程进行业务处理,完成后将响应结果发给 Handler 进行处理。
  6. Handler 收到响应结果后通过 send 将响应结果返回给 Client。

优点

  • 可以充分利用多核 CPU 的处理能力

缺点

  • 多线程资源共享和访问处理会比较复杂,在主线程处理所有的连接、监听和响应也会出现性能瓶颈
1.3 主从 Reactor 多线程

主从 Reactor 多线程模型又在前面的模型基础上做了进一步优化,增加了子 Reactor ,如下图所示:

02.Netty线程模型03.png

整个流程大概可以分为以下几步

  • 主线程的 MainReactor 负责监听连接请求,收到连接请求会由 Acceptor 进行处理,成功建立连接之后 MainReactor 会把连接分派给 SubReactor ,由 SubReactor 监听和处理数据请求;
  • SubReactor 监听到数据请求,会派发给 Handler 处理,Handler 只会处理读取数据和发送数据部分,中间业务处理部分也是放在线程池中完成。

优点

  • MainReactorSubReactor 职责分明,一个处理连接事件,一个处理数据请求;
  • MainReactorSubReactor 交互逻辑比较简单,MainReactor 单向地将建立好的连接传递出去;
  • 多 Reactor 设计能在高并发场景拥有更好的性能。

缺点

  • 编程复杂度较高

主从 Reactor 多线程模式是业界非常成熟的服务器程序设计模式,在很多中间件中都使用到了这种模式,像 Nginx、Memcached、Netty 等。这种模式也被称为 1 + M + N 模式,分别代指相对少的连接线程(不一定为 1 ),多个 I/O 线程和多个业务处理线程。

二、Netty 线程模型

Netty 线程模型是基于主从 Reactor 多线程模型优化而来的,整体架构如下图所示:

02.Netty线程模型04.png

Netty 的线程模型主要分为两部分,分别是 BossGroupWorkerGroup,它们都分别管理一个或多个 NioEventLoop。每个 NioEventLoop 对应着一个线程,一个 Selector,一个 Executor 和一个 TaskQueue

NioEventLoop 可以理解成一个事件循环,当程序启动后每个 NioEventLoop 都会通过 Executor 启动一个线程,开始执行事件循环,在循环中 Selector 会通过 select 方法阻塞并监听就绪事件,当有事件到来时通过 processSelectedKeys 方法处理 Selector 事件,之后再通过 runAllTasks 方法处理其他的任务。

与前面介绍的 主从 Reactor 多线程模型类似,BossGroup 负责连接事件,当建立连接之后会生成一个 NioSocketChannel 并注册到 WorkGroup 其中一个 NioEventLoop 的 Selector 上。WokerGroup 中的 NioEventLoop 负责处理数据请求,当请求到来时会调用 processSelectedKeys 方法,其中的业务处理会依次经过 Pipeline 中的多个 Handler。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值