Netty——Reactor模式及Netty模型


JAVA后端开发知识总结(持续更新…)


Netty——Reactor模式及Netty模型



一、Netty概述

1.1 NIO的问题

  1. NIO 的类库和 API 繁杂,使用麻烦。

  2. 对多线程和网络编程需要非常熟悉,才能编写出高质量的 NIO 程序。

  3. 容易遇到客户端面临断连重连、网络闪断、半包读写、失败缓存、网络拥塞和异常流的处理等问题。

  4. JDK NIO 的 Epoll Bug,它会导致 Selector 空轮询,最终导致 CPU 100%。

1.2 Netty简介

Netty框架

在这里插入图片描述

二、线程模型

线程模型分类

  • 传统阻塞I/O模型

  • Reactor模式

2.1 传统阻塞I/O模型

  • 每个连接需要独立的线程处理

  • 在read()处阻塞,造成资源浪费

  • 高并发时占用大量系统资源

在这里插入图片描述

2.2 Reactor模式

  Reactor模式是通过一个或多个输入同时传递给服务处理器的模式(基于事件驱动)。服务端程序会处理传入的多个请求,并将它们同步分派到相应的处理线程,因此Reactor模式也叫Dispatcher模式。Reactor模式使用IO多路复用监听事件,在监听到事件后,会分发给某个线程 / 进程。

  Reactor:1. 反应器模式;2. 分发者模式;3. 通知者模式。根据Reactor的数量和处理资源池线程的数量不同,分为三种类型:

  • 单Reactor + 单线程
  • 单Reactor + 多线程
  • 主从Reactor + 多线程

  Netty线程模型主要基于主从Reactor + 多线程模型做了一定的改进,主从Reactor多线程模型中有多个Reactor。

  Reactor模式针对传统阻塞I/O模型的2个缺点进行了优化:

  • 基于 I/O 多路复用模型:多个连接共用一个阻塞对象,应用程序只需在一个阻塞对象处等待,无需阻塞等待所有连接。当某个连接有新的数据可以处理时,操作系统通知应用程序,线程从阻塞状态返回,开始进行业务处理。
  • 基于线程池复用线程资源:不必再为每个连接创建线程,将连接完成后的业务处理任务分配给线程进行处理,一个线程可以处理多个连接的业务。

在这里插入图片描述

Reactor模式中的核心组成部分

  • Reactor

  Reactor在一个单独的线程中运行,负责监听和分发事件,分发给适当的处理程序来对IO事件作出反应。

  • Handlers

  处理程序执行I/O事件要完成的实际事件,Reactor通过调度适当的处理程序来响应I/O事件,处理程序执行非阻塞操作

2.2.1 单Reactor + 单线程

  1. Select 是前面 I/O 多路复用模型介绍的标准网络编程 API,可以实现应用程序通过一个阻塞对象监听多路连接请求。
  2. Reactor 对象通过 Select 监控客户端请求事件,收到事件后通过 Dispatch 进行分发。
  3. 如果是建立连接请求事件,由 Acceptor 通过 Accept 处理连接请求,然后创建一个 Handler 对象处理连接完成后的后续业务处理。
  4. 如果不是建立连接事件,则 Reactor 会分发调用连接对应的 Handler 来响应。
  5. Handler 会完成 Read + 业务处理 + Send 的完整业务流程。

在这里插入图片描述

优点:

  模型简单,没有多线程、进程通信、竞争的问题,全部都在一个线程中完成。

缺点:

  只有一个线程,无法完全发挥多核 CPU 的性能,Handler 在处理某个连接上的业务时,容易导致性能瓶颈。同时线程意外终止,或者进入死循环,会导致整个系统通信模块不可用,不能接收和处理外部消息。

2.2.2 单Reactor + 多线程

  1. Reactor 对象通过select 监控客户端请求事件,收到事件后,通过Dispatch进行分发。
  2. Handler 只负责响应事件,不做具体的业务处理,通过read 读取数据后,会分发给后面的Worker线程池的某个线程处理业务。
  3. Worker 线程池会分配独立线程完成真正的业务,并将结果返回给Handler。
  4. Handler收到响应后,通过send 将结果返回给Client。

在这里插入图片描述

2.2.3 主从Reactor + 多线程

  1. Reactor主线程 MainReactor 只注册一个用于监听连接请求的ServerSocketChannel,通过select 监听连接事件, 收到事件后,通过Acceptor 处理连接事件。
  2. 当 Acceptor 处理连接事件后,MainReactor 通过accept获取新的连接,并将连接注册到SubReactor
  3. Subreactor 将连接加入到连接队列进行监听,并创建Handler进行各种事件处理。
  4. Worker 线程池分配独立的worker 线程进行业务处理,并返回结果给SubReactor的Handler。
  5. Reactor 主线程可以对应多个Reactor 子线程,即MainRecator 可以关联多个SubReactor。

在这里插入图片描述

三、Netty模型

3.1 示例模型

  Netty主要是基于主从Reactor + 多线程模型做了一定的改进,其中主从Reactor多线程模型有多个Reactor。

  1. BossGroup维护多个主Reactor,主Reactor还是只关注连接的Accept。
  2. WorkGroup来维护多个从Reactor,从Reactor将接收到的请求交给Handler进行处理。
  3. 在主Reactor中接收到Accept事件,获取到对应的SocketChannel,Netty会将它进一步封装成NIOSocketChannel对象,包含有该Channel对应的SelectionKey、通信地址等。
  4. Netty会将封装后的Channel对象注册到WorkerGroup中的从Reactor中。
  5. 当WorkerGroup中的从Reactor监听到事件后,就会将之交给与此Reactor对应的Handler进行处理

在这里插入图片描述

3.2 详细模型

  1. Netty抽象出两组线程池,BossGroup专门负责接收客户端的连接,WorkerGroup专门负责网络的读写。

  2. BossGroup和WorkerGroup类型的本质都是NioEventLoopGroup类型。

  3. NioEventLoopGroup相当于一个线程管理器(类似于ExecutorServevice),即事件循环组,维护多个NioEventLoop线程,每个事件即对应一个NioEventLoop线程。

  4. NioEventLoop表示一个不断循环地执行处理任务的线程,它维护了一个Selector任务队列,内部采用串行化设计。

  5. 每个NioEventLoop都包含一个Selector,用于监听绑定在它上面的Socket通讯,负责处理多个NioChannel上的事件。

  6. 每个NioChannel只会绑定在唯一的NioEventLoop上,并且都绑定有一个Channel Pipeline。

  7. 每增加一个请求连接,NioEventLoopGroup就将这个请求依次分发给它下面的NioEventLoop处理。

  8. 处理业务时会使用Pipeline,Pipeline中维护了一个ChannelHandlerContext链表,ChannelHandlerContext保存了Channel相关的所有上下文信息,同时关联一个ChannelHandler对象。Channel和Pipeline一一对应,ChannelHandler和ChannelHandlerContext一一对应。

  9. ChannelHandler是一个接口,负责处理或拦截I/O操作,并将其转发到Pipeline中的下一个Handler进行处理。

  • Netty模型

在这里插入图片描述

  • Pipeline管道模型

在这里插入图片描述

Boss NioEventLoop循环执行:

  • 轮询accept事件;
  • 处理accept事件,与client建立连接,生成NioSocketChannel,并将其注册到某个Worker NioEventLoop的selector上;
  • 处理任务队列到任务,即runAllTasks。

Worker NioEventLoop循环执行:

  • 轮询read、write事件;
  • 处理I/O事件,即read、write事件,在对应的NioSocketChannel中进行处理;
  • 处理任务队列的任务,即runAllTasks。

NioEventLoopGroup补充:

  • 在初始化两个Group线程组时,默认会在每个Group中生成CPU * 2个NioEventLoop线程。
  • 当有n个连接时,Group默认会按照连接请求的顺序分别将这些连接分发给各个NioEventLoop去处理。
  • Group还负责管理EventLoop的生命周期
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值