netty浅述

Posted by KANG's BLOG on Tuesday, May 18, 2021

定义

Netty是一款基于NIO(Nonblocking I/O,非阻塞IO)开发的网络通信框架,其包含以下优点:

  • 封装JDK自带NIO的API
  • 可靠性能力补齐
  • 高性能,高吞吐量,低资源消耗

特点

NIO

传统BIO模型如下:

img

一个请求Socket请求都有对应一个Thread来承接,由于Thread数量有限,所以该模式不支持高并发,且Thread执行过程中会阻塞请求。

而NIO模型如下:

img

Selector处理所有请求,断开请求和处理线程的耦合,达到多路复用的目的,从而提高并发。

Linux提供select、poll、epoll三种方式来实现IO多路复用,Linux 2.6内核正式引入epoll,其采用Reactor模式实现,完全基于事件驱动,性能相比select和poll有较大提升,Netty、Nginx、Redis等组件中对于网络IO的处理,均使用epoll。

Netty的线程模型

Netty内部实现了两个线程池,boss线程池work线程池,其中boss线程池的线程负责处理请求的accept事件,当接收到accept事件的请求时,把对应的socket封装到一个NioSocketChannel中,并交给work线程池,其中work线程池负责将请求的read和write事件分发给对应的Handler处理。

零拷贝

一般我们的数据如果需要从IO读取到堆内存,中间需要经过Socket缓冲区,也就是说一个数据会被拷贝两次才能到达他的的终点。

针对这种情况,当Netty需要接收数据的时候,他会在堆内存之外开辟一块内存,数据就直接从IO读到了那块内存中去,在Netty里面通过ByteBuf可以直接对这些数据进行直接操作,从而加快了传输速度。

Netty核心组件

Channel

Channel是Java NIO的一个基本构造,它代表一个实体的开放连接,包括读写操作。

可以把Channel看作是数据传输的载体。

Callback

回调是常用的被调用方触发调用方的编程方式之一,Netty内部使用回调的方式来处理事件。

Future

Future提供了另一种在操作完成时通知应用程序的方式。

这个对象可以看作是一个异步操作的结果的占位符;它将在未来的某个时刻完成,并提供对其结果的访问。

比如ChannelFuture.connect()方法,作用是异步连接远程节点,方法直接返回,不会阻塞。

Event和ChannelHandler

Netty是基于事件驱动的,所以内部定义了非常多的事件。

事件按照入站或出站数据流的相关性进行分类的,其中入站数据或者相关的状态更改而触发的事件包括:

  • 连接已被激活或者连接失活

  • 数据读取

  • 用户事件

  • 错误事件

出站事件是未来将会触发的某个动作的操作结果,这些动作包括:

  • 打开或者关闭到远程节点的连接

  • 将数据写到或者冲刷到套接字

这些事件都可以被分发给ChannelHandler类中的某个用户实现的方法,你可以把ChannelHandler当作为处理特定事件而执行的回调。

常用API