共计 1655 个字符,预计需要花费 5 分钟才能阅读完成。
ByteBuf
JDK 原生 ByteBuffer 的外围性能
- 字节缓冲区,次要对字节进行操作的一个类
- 可能将缓冲区建设在堆内和堆外。一般的 new byte[] , 都只是建设在堆内
Netty 之所以要本人封一套 ByteBuf 的次要起因是:
- 原生 ByteBuffer 容量固定,一旦调配不能动静扩容和膨胀。
- 原生 ByteBuffer 的 API 应用不够优雅。稍有不慎,应用将会出错。它有 3 个外围指针,别离为 position、limit、capacity。position : 地位,示意缓冲区中正在操作数据的地位。limit : 界线,示意缓冲区中能够操作数据的大小,(limit 后数据不能进行读写)capacity : 容量。读写须要调用 flip()、rewind()、clear() 等办法来挪动相干指针。
ByteBuf 呢?它应用了外围的两个地位指针来帮助读写操作 java 培训,别离为 readerIndex 和 writerIndex, 数据读取 readerIndex 会减少,数据写入 writerIndex 会减少,不须要减少额定的操作来挪动相干指针。此外 readerIndex 是不可能超过 writerIndex。读取过 的 0 ~ readerIndex 这部分空间是被视为弃用的,同时它能够进行主动扩容。
Channel
Channel 是网络操作抽象类,聚合了一组性能,提供了比原生 Java SocketChannel、ServerSocketChannel 大而全的性能接口,供业务开发者应用,包含但不限于网络的读、写、发动连贯、敞开连贯、获取通信单方的地址。
UnSafe
Channel 的辅助操作类,操作底层网络 I /O,都是由它负责实现。
ChannelPipeLine
是 Channel 数据管道的一个形象,音讯在 ChannelPipeLine 中流动和传递。它依据 I / O 事件的类型,将消息传递给 ChannelHandler 进行解决。同时对 ChannelHandler 链表进行治理和调度。在读取数据时,ChannelHandler 链表的调度程序是 ch1,ch2,ch3,写数据时调度程序为 ch3,ch2,ch1。能够说它是 ChannelHandler 的一个治理容器。
ChannelHandler
解决相应 I / O 事件的通道音讯处理器,比方,读事件、写事件、读实现事件、写实现事件等,Netty 中泛滥的编解码器等都是实现自 ChannelHandler。
ChannelHandlerContext
通道处理器上下文,通过它来实现 Channel、ChannelPipeline、ChannelHandler 这几个组件之间的交互,采纳常识最小化准则让每个组件只关怀 ChannelHandlerContext 相干 API,。
ok, 咱们来大抵梳理一下对于通道的几个外围类关系。
- 每个 Channel 会绑定一个 ChannelPipeline,ChannelPipeline 中也会持有 Channel 的援用
- ChannelPipeline 持有 ChannelHandlerContext 链路,保留 ChannelHandlerContext 的头尾节点指针
- 每个 ChannelHandlerContext 会对应一个 ChannelHandler,也就相当于 ChannelPipeline 持有 ChannelHandler 链路
- ChannelHandlerContext 同时也会持有 ChannelPipeline 援用,也就相当于持有 Channel 援用
NioEventLoopGroup
Netty 遵循 Reactor 根底线程模型的一个具体实现。以下是 Reactor 几种根底线程模型介绍。
Reactor 单线程模型,所有的 I / O 操作都在同一个线程上实现。
Reactor 多线程模型,有一个用于专门接管客户端 TCP 连贯的 NIO 线程,网络 I /O 读、写操作有专门一个 NIO 线程池解决。
主从 Reactor 多线程模型,专门接管客户端 TCP 连贯的不在是一个线程,而是一个独立的线程池(主),网络 I /O 读、写操作依然是专门一个 NIO 线程池解决(从)