Netty线程模型

文章介绍了IO模型的三种类型——BIO、NIO和AIO,强调了阻塞与非阻塞、同步与异步的区别。重点讨论了Netty的线程模型,包括单线程、单Reactor多线程和主从Reactor多线程模型。Netty使用BossGroup和WorkerGroup来分别处理连接和网络读写,优化了内存访问和实现了零拷贝技术,以提高性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

IO模型

一、分类

BIO: 同步阻塞IO

NIO: 非阻塞同步IO

AIO: 非阻塞异步IO

二、区别分类

2.1 什么是阻塞

阻塞和非阻塞:

阻塞和非阻塞是相对于CPU来说的,持续占有CPU为阻塞,从磁盘读取数据到内核态的过程

2.2 什么是同步

同步和异步:

同步异步是相对于业务流程来说的,同步,前一步完成才能继续后面流程否则等待,从内核态到用户态的过程

IO操作分两个阶段

第1个阶段:等待数据准备好(从外部设备磁盘或网络读到内核缓冲区);
第2个阶段:采用系统调用(内核进程),操作系统内核将数据从内核缓冲区读到用户空间。
第1阶段花费的时间远远大于第2阶段。

三、Netty的线程模型

3.1、reactor单线程模型

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

在这里插入图片描述

 3.2  单 Reactor 多线程

Reactor 对象通过select 监控客户端请求事件, 收到事件后,通过dispatch进行分发,如果建立连接请求, 则由Acceptor 通过accept 处理连接请求, 然后创建一个Handler对象处理完成连接后的各种事件如果不是连接请求,则由reactor分发调用连接对应的handler 来处理,handler 只负责响应事件,不做具体的业务处理,通过read 读取数据后,会分发给后面的worker线程池的某个线程处理业务worker 线程池 会分配独立线程完成真正的业务,并将结果返回给handler,handler收到响应后,通过send 将结果返回给 client。

在这里插入图片描述

3.3 主从 Reactor 多线程

        Reactor主线程只负责accept建立连接,然后分发给Reactor子线程再次进行分发处理。

在这里插入图片描述

四、netty线程模型

学习连接:Netty线程模型_顽石九变的博客-优快云博客

BossGroup 线程维护Selector , 只关注Accecpt;
当接收到Accept事件,获取到对应的SocketChannel, 封装成 NIOScoketChannel并注册到 Worker 线程(事件循环),并进行维护;
当Worker线程监听到selector 中通道发生自己感兴趣的事件后,就进行处理(就由handler), 注意 handler 已经加入到通道。

在这里插入图片描述

Nett y抽象出两组线程池:BossGroup 和 WorkerGroup
BossGroup 专门负责接收客户端的连接
WorkerGroup 专门负责网络的读写
BossGroup 和 WorkerGroup 类型都是 NioEventLoopGroup,NioEventLoopGroup 相当于一个 事件循环组,这个组中 含有多个事件循环 ,每一个事件循环是 NioEventLoop,NioEventLoop 表示一个不断循环的执行处理任务的线程,每个NioEventLoop 都有一个selector , 用于监听绑定在其上的socket的网络通讯。
NioEventLoopGroup 可以有多个线程, 即可以含有多个NioEventLoop
每个BossGroup 中的 NioEventLoop 循环执行的步骤:
1)轮询accept 事件。
2)处理accept 事件,与client建立连接 , 生成 NioScocketChannel,并将其注册 Worker Group 上的某个 NIOEventLoop 上的 selector。
3)处理任务队列的任务,即 runAllTasks。
每个 Worker Group 中的 NIOEventLoop 循环执行的步骤:
1)轮询 read/write 事件
2)处理 I/O 事件, 即 read/write 事件,在对应的 NioScocketChannel 上处理
3)处理任务队列的任务 , 即 runAllTasks
        每个Worker NIOEventLoop 处理业务时,会使用 pipeline(管道)。pipline中包含了 channel,即通过pipline可以获取到对应的 channel,并且pipline维护了很多的 handler(处理器)来对我们的数据进行一系列的处理。
handler(处理器) 有Netty内置的,我们也可以自己定义。 

在这里插入图片描述

五、直接内存访问为什么比堆内存快

5.1 堆内存访问

        如果是堆内存访问,堆内存->直接内存->socket缓冲区,为了防止垃圾回收内存地址变化数据拷贝错误或者失败。

5.2 直接内存访问

        如果是直接内存访问,则直接从堆内存->socket缓冲区;节省了大部分时间

六、 零拷贝

 零拷贝分多种分别涉及到的技术为:DMA, mmap, fileSend, slice, 零拷贝

物理 升级实现零拷贝 将一部分拷贝工作 从 CPU -> DMA,减少了一次cpu使用

mmap 用户态内存映射到内核态?

fileSend 实现内核之间的数据拷贝,略过用户态,内核态的socket和内存建立映射,cpu只需要传送index和大小即可

slice 建立pipe管道,不再使用cpu进行零拷贝,linux 2.6.17之后才有的?

6.1 原始内存拷贝

buffer = FIle.read;

Socket.send(buffer);  涉及四次内存拷贝

引入硬件DMA,减少2次CPU拷贝,改用DMA拷贝

Java 两种zero-copy零拷贝技术mmap和sendfile的介绍_sendfile没法修改数据-优快云博客

 

 

参考链接:redis的IO多路复用以及select,epoll的演进 - 墨天轮

7、NettyClient持续发送造成的oom

Netty使用案例 -发送队列积压导致内存泄漏(一)_netty nioeventloopgroup 内存过高_青0721松的博客-优快云博客

8、Netty架构模型

Netty 的整体架构是怎样的? - 掘金 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值