Netty 学习笔记(一)

344 阅读3分钟

这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战

正文

个人理解:基于NIO的java网络编程框架,可以异步处理socket请求、长连接等

Netty-model.png

NIO 和BIO区别

BIO

BIO.png

NIO

NIO.png BIO 是在接收客户端的请求数据时默认是多线程模式,也就是说一个请求一个线程,这样高并发的时候容易造成服务器压力,

NIO 则是采用单线程模式,当一个Socket建立好之后,Thread并不会阻塞去接受这个Socket,而是将这个请求交给Selector,Selector会不断的去遍历所有的Socket,一旦有一个Socket建立完成,他会通知Thread,然后Thread处理完数据再返回给客户端——这个过程是阻塞的,这样就能让一个Thread处理更多的请求了。

传输快:

  • 原因一:非阻塞读取数据

传统硬件的堵塞如下,从内存中读取数据,然后写到磁盘,而CPU一直等到磁盘写完成,磁盘的写操作是慢的,这段时间CPU被堵塞不能发挥效率。

NIO模式下,CPU只是发出写操作的指令,具体由DMA(Direct Memory Access 直接存储器存取)执行,DMA处理完数据之后会将中断事件传给CPU告诉它操作结束,这段时间内CPU处于空闲状态,可以进行其他操作

  • 原因二:

NIO 传输快的另一个原因是--零拷贝,传统的拷贝流程都会讲数据先存在缓存区中,然后从缓存区中读取数据,或者读数据。零拷贝是直接将数据存在临时的内存块中,然后通过ByteBuf直接去读取数据

核心组件

Channel:

管道或者通道,对应一个socket连接,类似于JDK中提供的nio包下channel,在netty中有独有的channel类---io.netty.channel.Channel是Netty框架自己定义的一个通道接口,Netty实现的客户端NIO套接字通道是NioSocketChannel,提供的服务器端NIO套接字通道是NioServerSocketChannel。

目前,可以把 Channel 看作是传入(入站)或者传出(出站)数据的载体。因此,它可以被打开或者被关闭,连接或者断开连接。

生命周期

image.png

ChannelHandler

4.0 及以上

处理channel中的业务逻辑,个人理解有点类似于tomcat中处理请求 的前置、后置处理、启动、销毁这些方法的封装接口

void handlerAdded(ChannelHandlerContext var1) throws Exception;

void handlerRemoved(ChannelHandlerContext var1) throws Exception;

分类:

  • ChannelInboundHandler to handle inbound I/O events,(处理从客户端来的请求),并在ChannelPipeline中按照从上至下的顺序查找调用相应的ChannelInboundHandler。
  • ChannelOutboundHandler to handle outbound I/O operations.(处理返回客户端的请求)并在ChannelPipeline中按照从下至上的顺序查找调用相应的ChannelOutboundHandler。

ChannelPipeline

因为一个channel可能有多个ChannelHandler,所以需要一个存储的环境,ChannelPipeline作用就在于此

类似于Tomcat容器中的Filter链,属于设计模式中的责任链模式,其中还保存了ChannelHandlerContext

ChannelPipeline.png

每当一个新的Channel被创建了,都会建立一个新的 ChannelPipeline,并且这个新的 ChannelPipeline 还会绑定到Channel上。这个关联是永久性的;Channel 既不能附上另一个 ChannelPipeline 也不能分离当前这个。这些都由Netty负责完成,,而无需开发人员的特别处理。