简介

简介:Netty是 一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。

在前面的文章里我介绍了几种I/O模型的,netty则是基于其中的复用I/O实现的。I/O多路复用机制都依赖于一个事件分发器,事件分离器把接收到的客户事件分发到不同的事件处理器中。netty01:netty模型 - 图1

Proactor(异步)和Reactor(同步)是两种经典的多路复用I/O模型,主要用于在高并发、高吞吐量的环境中进行I/O处理。其中netty采用的就是Reactor。下面就来就来介绍下Reactor

Reactor模型

1、 Reactor模式结构

特点:

  1. 事件驱动(event handling)
  2. 可以处理一个或多个输入源(one or more inputs)
  3. 通过Service Handler同步的将输入事件(Event)采用多路复用分发给相应的Request Handler(多个)处理

image.png

netty01:netty模型 - 图3

Handle 句柄;用来标识socket连接或是打开文件;

Synchronous Event Demultiplexer:同步事件多路分解器:由操作系统内核实现的一个函数;用于阻塞等待发生在句柄集合上的一个或多个事件;(如select/epoll;)

Event Handler:事件处理接口

Concrete Event HandlerA:实现应用程序所提供的特定事件处理逻辑;

Reactor:反应器,定义一个接口,实现以下功能:

1)供应用程序注册和删除关注的事件句柄;

2)运行事件循环;

3)有就绪事件到来时,分发事件到之前注册的回调函数上处理;

2、单reactor单线程模型

方案说明:Select是IO复用模型介绍的标准网络编程API,可以实现应用程序通过一个阻塞对象监听多路连接请求

  • Reactor对象通过Select监控客户端请求事件,收到事件后通过Dispatch进行分发
  • 如果是建立连接请求事件,则由Acceptor通过Accept处理连接请求,然后创建一个Handler对象处理连接完成后的后续业务
  • 如果不是建立连接事件,则Reactor会分发调用连接对应的Handler来处理业务
  • Handler会完成Read->业务处理->Send的完整业务流程


image.png
这种模式的缺点在于:

  • 服务器端用一个线程通过多路复用搞定所有的IO操作,包括连接、读、写等,但是如果客户端连接数较多,将无法支撑,比如处理一个客户端的业务时,别的客户端的业务请求只能阻塞等待
  • 单线程无法发挥多核CPU的性能

    3、单Reactor多线程

  • Reactor对象通过select监控客户端请求事件,收到事件后,通过dispatcher进行分发如果是建立连接的请求,则由Acceptor通过accept处理连接请求,然后创建一个Handler对象处理完成连接后的各种事件

  • 如果不是连接请求,则由Reactor分发调用连接对应的handler进行处理
  • handler只负责响应事件,不做具体的业务处理,通过read读取数据后,会分发给后面的worker线程池的某个线程处理业务
  • worker线程池会分发独立的线程完成真正的业务,并将结果返回给handler
  • handler收到响应的结果后,再通过send将结果返回给client

image.png
优点:

  • 多线程可以充分利用多核CPU的处理能力
  • 采用线程池复用线程,减少创建和销毁线程带来的性能开销

缺点:

  • reactor处理所有事件的监听和响应,在单线程运行,高并发场景下容易出现性能瓶颈
  • 多线程数据共享和访问比较复杂

    4、主从Reactor多线程

  • Reactor主线程MainReactor对象通过select监听连接事件,收到事件后,通过Acceptor处理连接事件

  • 当Acceptor处理连接事件后,MainReactor将连接分配给SubReactor

  • SubReactor将连接加入到连接队列进行监听,并创建handler进行各种事件处理

  • 当有新事件发生时,SubReactor就会调用对应的handler进行处理

  • handler通过Read读取数据,分发给后面的worker线程处理

  • worker线程池会分配独立的worker线程进行业务处理,并返回结果

  • handler收到响应的结果后,再通过send将结果返回给client

  • MainReactor主线程可以关联多个SubReactor子线程


image.png
优点:
主线程与子线程的数据交互简单职责明确,主线程只需要接收新连接,子线程完成后续的业务处理

  • 可以通过扩展多个Reactor子线程的方式来减小单个子线程的压力,提高并发处理能力

  • Netty就是在主从Reactor多线程模型的基础上进行了一定的改进,同时,Kafka的网络架构设计也采用了这种主从Reactor多线程的模型。

补充

1、什么是句柄

https://blog.csdn.net/weixin_44358168/article/details/115868153

参考

https://www.cnblogs.com/billmiao/p/9872222.html

https://www.jianshu.com/p/da96ff9066a3

https://blog.csdn.net/weixin_39615991/article/details/113492375

https://blog.csdn.net/qq924862077/article/details/81026740