Netty 线程模型:

图好:https://juejin.im/post/6844903712435994631
解析好:https://blog.csdn.net/y277an/article/details/98561000
Netty 采用基于主从 Reactors 多线程模型:

  • mainReactor 负责客户端的连接请求,并使用队列转交给 subReactor
  • subReactor 负责处理通道的 IO 读写请求

线程池:

  • bossGroup:一个端口对应一个线程,同时对应一个 mainReactor
  • workerGroup:被 subReactor 和 worker 线程充分利用

线程模型 - 图1


Reactor 线程模型:

https://www.jianshu.com/p/2965fca6bb8f
也叫 Dispatcher 模型,即 IO 多路复用统一监听事件,收到事件后分发。
组成:

  • Reactor:单独的线程运行,负责监听和分发事件,分发给适当的处理程序
  • Handler:处理 Reactor 派发的 IO 事件

线程模型 - 图2
根据 Reactor 和 Handler 线程数量,分为三种:

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

单 Reactor 单线程:

线程模型 - 图3

  1. Reactor 对象通过 select 监控连接事件,收到事件后通过 dispatch 进行转发。
  2. 如果是连接建立的事件,则由 acceptor 接受连接,并创建 handler 处理后续事件。
  3. 如果不是建立连接事件,则 Reactor 会分发调用 Handler 来响应。
  4. handler 会完成 read -> 业务处理 -> send 的完整业务流程。


缺点:**

  1. Reacor、Acceptor、Handler 都是一个线程处理,利用不了多核 CPU
  2. 单线程同时负责 Handler 的编码、解码、读取和发送,负载过重,吞吐量低
  3. 单线程发生故障后,会造成进程崩溃

主线程:

  • Reactor:
    • 调用 Acceptor.accept,创建 Handler
    • dispatch,调用 Handler
  • Handler:read、write、业务

单 Reactor 多线程:

线程模型 - 图4

  1. Reactor 对象通过 Select 监控客户端请求事件,收到事件后通过 dispatch 进行分发。
  2. 如果是建立连接请求事件,则由 acceptor 通过 accept 处理连接请求,然后创建一个 Handler 对象处理连接完成后续的各种事件。
  3. 如果不是建立连接事件,则 Reactor 会分发调用连接对应的 Handler 来响应。
  4. Handler 只负责响应事件不做具体业务处理,通过 Read 读取数据后,会分发给后面的 Worker 线程池进行业务处理。
  5. Worker 线程池会分配独立的线程完成真正的业务处理,如何将响应结果发给 Handler 进行处理。
  6. Handler 收到响应结果后通过 send 将响应结果返回给 Client。

主线程:

  • Reactor:
    • 调用 Acceptor.accept,创建 Handler
    • dispatch,调用 Handler
  • Handler:read、write

work 线程:业务

缺点:

  1. 多线程数据共享和访问复杂。work 线程把数据给主线程发送,会涉及到共享数据的互斥和保护机制
  2. 主线程同时负责 Reactor 和 Handler,即 accept、read、write,存在性能问题

主从 Reactor 多线程:

线程模型 - 图5

  1. 主线程池中随机选择一个 Reactor 线程作为 acceptor 线程,用于绑定监听端口接收客户端连接
  2. acceptor 线程接收客户端连接请求之后创建新的 SocketChannel,将其注册到主线程池的其它 Reactor 线程上,由其负责接入认证、IP 黑白名单过滤、握手等操作
  3. 步骤 2 完成之后,业务层的链路正式建立,将 SocketChannel主线程池的 Reactor 线程的多路复用器上摘除重新注册到 Sub 线程池的线程上,并创建一个 Handler 用于处理各种连接事件
  4. 当有新的事件发生时,SubReactor 会调用连接对应的 Handler 进行响应
  5. Handler 通过 Read 读取数据后,会分发给后面的 Worker 线程池进行业务处理
  6. Worker 线程池会分配独立的线程完成真正的业务处理,如何将响应结果发给 Handler 进行处理
  7. Handler 收到响应结果后通过 Send 将响应结果返回给 Client

Proactor 模型: