当前位置: 首页 > news >正文

Netty笔记1:线程模型

Netty笔记1:线程模型

Netty笔记2:零拷贝

Netty笔记3:NIO编程

Netty笔记4:Epoll

Netty笔记5:Netty开发实例

Netty笔记6:Netty组件

Netty笔记7:ChannelPromise通知处理

Netty笔记8:ByteBuf使用介绍

Netty笔记9:粘包半包

Netty笔记10:LengthFieldBasedFrameDecoder

Netty笔记11:编解码器

Netty笔记12:模拟Web服务器

Netty笔记13:序列化

文章目录

  • 前言
  • 单线程Reactor模型
  • 单线程Reactor工作者线程池模型
  • 多线程Reactor模型
  • 与BIO对比

前言

该篇纯理论,说明NIO线程模型,为后续原理和运用打下基础,是知识和运用易于理解。

单线程Reactor模型

Reactor接收到请求,交由Acceptor事件处理器(accept事件的处理器),建立socket连接,加入队列,并监听着这个连接,当监听到读取事件,就交由对应空闲的处理器处理,一些业务操作如解码,响应等,从连接到响应都是由一个线程完成;
这里的操作就是事件,他们耗时长短不一,多个请求来时,就可以根据操作由不同的处理器完成;

流程如下:

  1. 服务端reactor线程对象,会启动一个事件循环,并使用selector来实现IO的多路复用。注册一个Accept的事件处理器AcceptorReactor中,Reactor就会监听客户端向服务端发起的连接请求事件(Accept事件);

  2. 客户端向服务端发起一个连接请求,Reactro监听到了该事件(Accept事件),并将该事件派发给对应的Acceptor处理器。Acceptor处理器通过accept()方法就可以得到对应客户端的连接(SocketChannel),之后注册一个Read事件处理器到Reactor中,让它监听Read事件;

  3. Reactor监听到读或写的事件,就会加将事件派发给对应的处理器,不会阻塞等待;

  4. 每当处理完事件后,Reactor会再次执行select()阻塞等待新事件就绪并将其派发给对应的处理器;

    image-20240512192552796

注意:

  • Reactor的单线程模式主要针对IO操作而已,也就是所有IO的accept()、read()、wriete()、connect()都在一个线程上完成。

  • 每个事件对应一个处理器,在Reactor模式中,需要先进行注册处理器,才能对事件监听和分派任务;

  • 在连接后,需要注册read事件处理器,而wirte事件处理器,这个也可以注册,但是相对来说,注册写事件后要的代码量更大,而且也没必要监听,向写的时候主动些就行,而读是被动的,再一点是再注册write事件后,没有数据要写时,要取消write的注册;

    为什么?

    OP_WRITE:当操作系统写缓冲区有空闲空间是就绪,一般情况下写缓冲都是空的,小数据直接写就行,没必要注册write事件,而大数据,很容易占满缓冲区,就很有必要注册,不管小数据还是大数据,写完后要注销这个write事件;

    OP_READ:当读缓冲区有数据可读时就绪,不是时刻都有数据,所以注册该操作,仅当有数据时进行读操作,避免CPU浪费。

单线程Reactor工作者线程池模型

单线程模式下,很多非I0的处理也是单线程的业务操作,将这些业务操作就交由线程池,如解码,计算。

优势:

  1. 重用现有的线程而不是创建新线程,可以在处理多个请求时分摊在线程创建和销毁过程产生巨大开销;
  2. 请求到达时,工作线程通常已经存在,因此不会由于等待创建线程而延迟任务的执行,从而提高了响应性;
  3. 通过适当调整线程池的大小,可以创建足够多的线程一边使处理器保持忙碌状态,同时还可以防止过多线程相互竞争资源而使应用程序耗尽内存或失败;

虽说线程池是增加了线程,可以提高工作性能,但是对于高负载、大并发或大数据量的应用场景却不合适:

  1. 要给NIO线程同时处理成百上千链路,性能上无法支持,即便NIO线程的CPU负荷打到100%,也无法满足海量消息的读取和发送;
  2. 当NIO线程负载过重后,处理速度变慢,会导致大量客户端连接超时,超时往往会进行重发,这更加重了NIO线程的负载,最终导致大量消息积压和处理超时,成为系统性能的瓶颈。

image-20240512192607288

多线程Reactor模型

大数据量下,单个线程的reactor忙于处理读取和发送,有些请求就无法处理;所以reactor就分出了mainReactor,和subReactor.
mainReactor处理请求的连接,subReactor可以有多个,处理业务与响应;

流程:

  1. 注册一个Accept的事件处理器到mainReactor中,让其关注Accept事件,这样mainReactor会监听客户端向服务器端发起的连接请求(accept事件);
  2. 客户端向服务器端发起连接请求,mainReactor监听到了该accept事件并将该事件派发给Acceptor处理器处理,Acceptor处理器通过accept()获取到客户端对应的连接(SocketChannel),然后将channel给subReactor线程池;
  3. subReactor线程池分配一个subReactor线程给SocketChannel,然后注册READ事件到这个channel上,让它监听;
  4. 当有IO事件就绪时,subReactor就将事件派发给对应的处理器;

注意:

mainReactor、subReactor还是处理accept()、read()、write()、connect()这些操作。

mainReactor只处理accept处理;

与BIO对比

我们看下面两种IO的流程对比:

image-20240512193558166

阻塞式IO就是BIO,复用IO比阻塞式IO多了一个通知,所以selector是可以处理多个连接,但是如果处理量不高的话,BIO还要比NIO快,NIO的优势是能处理更多的连接。

相关文章:

  • CTA策略【量化理论】
  • 项目工坊 | Python驱动淘宝信息爬虫
  • 大数据与网络安全讲座
  • 大模型在垂直行业的落地实践:从通用到定制化的技术跃迁
  • 洛谷 P2142 高精度减法(详解)c++
  • CSS Overflow 属性详解
  • C语言---猜数字游戏
  • Python Web应用开发之Flask框架——基础
  • 【第12节】C++设计模式(结构型模式)-Proxy(代理)模式
  • 第二章、python常用数据结构(2.3.1-2.4)------容器类型与容器类型的关系、数据类型与数据结构的关系
  • 3d投影到2d python opencv
  • 学习路程十三 结合之前所学进行 检索增强生成 实战
  • vuex中的state是响应式的吗?
  • 【每日论文】How far can we go with ImageNet for Text-to-Image generation?
  • 深度学习---卷积神经网络
  • 解锁Egg.js:从Node.js小白到Web开发高手的进阶之路
  • Vite:现代前端构建工具的新选择
  • 深入解析 MySQL 中的时间函数:NOW() 与 SYSDATE() 的奥秘
  • FPGA 配置原理
  • 计算机毕业设计SpringBoot+Vue.js工作流程管理系统(源码+文档+PPT+讲解)
  • 网站如何搬家/营销方法有哪些方式
  • 做网站建设跑业务/个人网站免费域名注册
  • 免费购物网站制作/seo课程多少钱
  • 网页设计师常逛网站/裤子seo标题优化关键词
  • 做外包的网站有哪些问题/微信销售平台
  • 手机网站自动跳转代码/爱奇艺科技有限公司