Netty线程模型

一、Reactor线程模型

Reactor模式思想:分而治之+事件驱动

Reactor模式首先是事件驱动的,有一个或多个并发输入源,有一个Service Handler,有多个Request Handlers;这个Service Handler会同步的将输入的请求(Event)多路复用的分发给相应的Request Handler

角色:

  • Reactor:负责响应事件,将事件分发给绑定了该事件的Handler处理;
  • Handler:事件处理器,绑定了某类事件,负责执行对应事件的Task对事件进行处理;
  • Acceptor:Handler的一种,绑定了connect事件。当客户端发起connect请求时,Reactor会将accept事件分发给Acceptor处理。

二、单线程模型

单线程模型下,所有的IO操作都由同一个Reactor线程来完成。
特点:

  1. 作为服务端,接收客户端的TCP连接;
  2. 作为客户端,向服务端发起TCP连接;
  3. 读取通信对端的请求或者应答消息;
  4. 向通信对端发送消息请求或者应答消息。

缺点:

  • 不能利用多核CPU;

  • 一个线程需要执行处理所有的accept、read、decode、process、encode、send事件,处理成百上千的链路时性能上无法支撑;

  • 一旦reactor线程意外跑飞或者进入死循环,会导致整个系统通信模块不可用

注意这里指的是基于Reactor的单线程模式,不是BIO的单线程

三、多线程模型

  1. 专门由一个Reactor线程-Acceptor线程用于监听服务端,接收客户端连接请求
  2. 网络I/O操作读、写等由Reactor线程池负责处理
  3. 一个Reactor线程可同时处理多条链路,但一条链路只能对应一个Reactor线程,这样可避免并发操作问题。

这种模式在绝大部分情况下都可以使用,但是如果客户端连接数量过多,并发量太大,只有一个Acceptor线程用来监听连接,会出现性能问题

四、主从多线程模型

  1. 从主线程池中随机选择一个 Reactor 线程作为 Acceptor 线程,用于绑定监听端口,接收客户端连接
  2. Acceptor 线程接收客户端连接请求之后创建新的 SocketChannel,将其注册到主线程池的其它 Reactor 线程上,由其负责接入认证、IP 黑白名单过滤、握手等操作
  3. 业务层的链路正式建立,将 SocketChannel 从主线程池的 Reactor 线程的多路复用器上摘除,重新注册到 Sub 线程池的线程上,用于处理 I/O 的读写操作

五、Netty线程模型

Netty同时支持Reactor单线程模型 、Reactor多线程模型和Reactor主从多线程模型,用户可根据启动参数配置在这三种模型之间切换

Netty 线程模型采用“服务端监听线程”和“IO线程”分离的方式,与多线程Reactor模型类似。抽象出NioEventLoop来表示一个不断循环执行处理任务的线程,每个NioEventLoop有一个selector,用于监听绑定在其上的socket链路

服务端客户端启动代码

  • ServerBootstrap 类用于创建服务端实例,Bootstrap 用于创建客户端实例。

  • bossGroup 线程组实际就是 Acceptor 线程池,负责处理客户端的 TCP 连接请求,如果系统只有一个服务端端口需要监听,则建议 bossGroup 线程组线程数设置为 1

  • workerGroup 是真正负责 I/O 读写操作的线程组,通过 ServerBootstrap 的 group 方法进行设置,用于后续的 Channel 绑定

  • 客户端只需要创建一个 EventLoopGroup,因为它不需要独立的线程去监听客户端连接,也没必要通过一个单独的客户端线程去连接服务端

NioEventLoop 是 Netty 的 Reactor 线程,职责如下:
  • 作为服务端 Acceptor 线程,负责处理客户端的请求接入;
  • 作为客户端 Connecor 线程,负责注册监听连接操作位,用于判断异步连接结果;
  • 作为 IO 线程,监听网络读操作位,负责从 SocketChannel 中读取报文;
  • 作为 IO 线程,负责向 SocketChannel 写入报文发送给对方,如果发生写半包,会自动注册监听写事件,用于后续继续发送半包数据,直到数据全部发送完成;
  • 作为定时任务线程,可以执行定时任务,例如链路空闲检测和发送心跳消息等;
  • 作为线程执行器可以执行普通的任务线程(Runnable)
NioEventLoop串行化设计避免线程竞争

系统在运行过程中,如果频繁的进行线程上下文切换,会带来额外的性能损耗,同时多线程运行的情况下,对于共享资源的读写,需要做额外的控制,防止出错。

为了解决上述问题,Netty 采用了串行化设计理念。

从消息的读取->解码->处理->编码->发送,始终由IO线程NioEventLoop负责。整个流程不会进行线程上下文切换,数据无并发修改风险。对于用户而言,甚至不需要了解 Netty 的线程细节,这确实是个非常好的设计理念。

一个NioEventLoop聚合一个多路复用器selector,因此可以处理多个客户端连接。

Netty 只负责提供和管理“IO线程”,其他的业务线程模型由用户自己集成。

时间可控的简单业务建议直接在“IO线程”上处理,复杂和时间不可控的业务建议投递到后端业务线程池中处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值