3-Netty的Reactor线程模型详解

3-Netty的Reactor线程模型详解,第1张

3-Netty的Reactor线程模型详解

文章目录
  • 一、Netty是什么?
  • 二、问题:有了NIO为啥还要用netty?
  • 三、netty的线程模型
    • 1. 传统阻塞I/O模型
    • 2. Reactor模型
      • 2.1 单Reactor单线程模型
      • 2.2 单Reactor多线程模型
        • 2.2.1 模型介绍
        • 2.2.2 方案优缺点分析:
      • 2.3 主从Reactor多线程模型
        • 2.3.1 方案优缺点分析:
        • 2.3.2 方案优缺点分析:
      • 3 总结


一、Netty是什么?

其实我们之前已经说了netty的定义和使用场景,具体可以看1-Netty的定义和使用场景。

二、问题:有了NIO为啥还要用netty?

其实通过对于NIO的学习,我们知道,基于NIO其实就可以实现网络编程,和网络通信,但是为啥我们还要基于netty来做这个事呢?
主要原因有如下几点:
1)这是因为nio算是比较底层的技术,并且基于nio编程比较复杂,他的类库和API比较繁杂,需要掌握selector,serversocketchannel,socketchannel,ByteBuffer
2)需要对多线程及网络编程特别熟悉,才能编写出比较好的代码
3)开发工作量和难度会加大,例如客户端面临断连重连,网络闪断,半包读写,失败缓存,网络拥塞和异常流的读写
4)JDK NIO的bug,:比如说Epoll bug,它会导致selector的空轮询

而相比之下netty其实有很多的优点:
Netty 对 JDK 自带的 NIO 的 API 进行了封装,解决了上述问题。

  1. 设计优雅:适用于各种传输类型的统一 API 阻塞和非阻塞 Socket;基于灵活且可扩展的事件模型,可以清晰 地分离关注点;高度可定制的线程模型 - 单线程,一个或多个线程池.
  2. 使用方便:详细记录的 Javadoc,用户指南和示例;没有其他依赖项,JDK 5(Netty 3.x)或 6(Netty 4.x)就 足够了。
  3. 高性能、吞吐量更高:延迟更低;减少资源消耗;最小化不必要的内存复制。
  4. 安全:完整的 SSL/TLS 和 StartTLS 支持。
  5. 社区活跃、不断更新:社区活跃,版本迭代周期短,发现的 Bug 可以被及时修复,同时,更多的新功能会被 加入
    总结就是 netty对NIO进行了封装,开发速度比较快,性能比较好,社区活跃,文档比较全
三、netty的线程模型

目前netty存在的线程模型有传统阻塞I/O模型 与 Reactor模式
而reactor模型细分起来又有单Reactor单线程,单Reactor多线程,主从Reactor多线程
而netty主要是针对主从Reactor模型作了一些改进。

1. 传统阻塞I/O模型

2. Reactor模型

正如1中所说传统阻塞io模型其实是存在问题–占用资源,造成阻塞
所以引入了Reactor模型,

具体来看 就是
1 基于io复用模型,说白了就是多个连接公用一个阻塞对象,应用程序只需要再一个阻塞对象等待,无需阻塞等待所有连接
2. 基于线程池复用线程资源,–即不必为每个连接创建线程,将连接完成后的业务处理任务分配给线程处理,一个线程可以处理多个连接(举例即如c1过来连接serviceHandler,然后线程1进行处理,然后c2过来连接,线程2进行处理,c3过来连接,线程3进行处理,c4过来连接,线程1处于空闲状态,这时就会由线程1来处理c4)

成型的reactor模式图如下:

2.1 单Reactor单线程模型

  1. Select 是前面 I/O 复用模型介绍的标准网络编程 API,可以实现应用程序通过一个阻塞对象监听多路连接请求
  2. Reactor 对象通过 Select 监控客户端请求事件,收到事件后通过 Dispatch 进行分发
  3. 如果是建立连接请求事件,则由 Acceptor 通过 Accept 处理连接请求,然后创建一个 Handler 对象处理连接 完成后的后续业务处理
  4. 如果不是建立连接事件,则 Reactor 会分发调用连接对应的 Handler 来响应
  5. Handler 会完成 Read→业务处理→Send 的完整业务流程
    结合实例:服务器端用一个线程通过多路复用搞定所有的 IO *** 作(包括连接,读、写等),编码简单,清晰明了, 但是如果客户端连接数量较多,将无法支撑,
    前面的 NIO 案例就属于这种模型。
2.2 单Reactor多线程模型 2.2.1 模型介绍

  1. Reactor 对象通过 select 监控客户端请求 事件, 收到事件后,通过 dispatch 进行分发
  2. 如果建立连接请求, 则有 Acceptor 通过 accept 处理连接请求, 然后创建一个 Handler 对象处理完成连接后的各种事件
  3. 如果不是连接请求,则由 reactor 分发调用连接对应的 handler 来处理
  4. handler 只负责响应事件,不做具体的业务处理, 通过 read 读取数据后,会分发给后面的 worker 线程池的某个 线程处理业务
  5. worker 线程池会分配独立线程完成真正的业务,并将结果返回给 handler
  6. handler 收到响应后,通过 send 将结果返回给 client
2.2.2 方案优缺点分析:
  1. 优点:可以充分的利用多核 cpu 的处理能力
  2. 缺点:多线程数据共享和访问比较复杂, reactor 处理所有的事件的监听和响应,在单线程运行, 在高并发场 景容易出现性能瓶颈.
2.3 主从Reactor多线程模型 2.3.1 方案优缺点分析:


1) Reactor 主线程 MainReactor 对象通过 select 监听连接事件, 收到事件后,通过 Acceptor 处理连接事件
2) 当 Acceptor 处理连接事件后,MainReactor 将连接分配给 SubReactor
3) subreactor 将连接加入到连接队列进行监听,并创建 handler 进行各种事件处理
4) 当有新事件发生时, subreactor 就会调用对应的 handler 处理
5) handler 通过 read 读取数据,分发给后面的 worker 线程处理
6) worker 线程池分配独立的 worker 线程进行业务处理,并返回结果
7) handler 收到响应的结果后,再通过 send 将结果返回给 client
8) Reactor 主线程可以对应多个 Reactor 子线程, 即 MainRecator 可以关联多个 SubReactor**

2.3.2 方案优缺点分析:
  1. 优点:父线程与子线程的数据交互简单职责明确,父线程只需要接收新连接,子线程完成后续的业务处理。
  2. 优点:父线程与子线程的数据交互简单,Reactor 主线程只需要把新连接传给子线程,子线程无需返回数据。
  3. 缺点:编程复杂度较高
3 总结

上述三种reactor模式可以通过生活案例来理解:

  1. 单 Reactor 单线程,前台接待员和服务员是同一个人,全程为顾客服
  2. 单 Reactor 多线程,1 个前台接待员,多个服务员,接待员只负责接待
  3. 主从 Reactor 多线程,多个前台接待员,多个服务生

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5694642.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存