netty入门
简单Server和简单Client
1 |
几大组件的关系
channel,eventLoopGroup,ByteBuf,Handler,pipline


EventLoop
事件循环对象,本质就是单线程执行器
事件循环组(EventLoopGroup),channel一般会调用EventLoopGroup中的register来绑定其中一个channel,后面channel上的io事件都由此EventloopGroup来负责,也保证了io处理时的线程安全
NioEventLoop 底层基于NIO
DefaultEventLoop
Channel
作用
- <font style="color:rgb(31, 35, 40);">close() 可以用来关闭 channel</font>
- <font style="color:rgb(31, 35, 40);">closeFuture() 用来处理 channel 的关闭</font>
* <font style="color:rgb(31, 35, 40);">sync 方法作用是同步等待 channel 关闭</font>
* <font style="color:rgb(31, 35, 40);">而 addListener 方法是异步等待 channel 关闭</font>
- <font style="color:rgb(31, 35, 40);">pipeline() 方法添加处理器</font>
- <font style="color:rgb(31, 35, 40);">write() 方法将数据写入</font>
- <font style="color:rgb(31, 35, 40);">writeAndFlush() 方法将数据写入并刷出</font>
注意 connect,bind 方法是异步的,意味着不等连接建立,方法执行就返回了。因此
channelFuture 对象中不能【立刻】获得到正确的 Channel 对象
两种方法:线程sync()阻塞等待建立好,addListener() 添加回调方法
Future & Promise
Handler & Pipeline
多个Handler组成一个pipeline
ByteBuf
是对字节数据的封装
创建
1 | ByteBuf buffer = ByteBufAllocator.DEFAULT.buffer(10);//默认使用 池化基于直接内存的 ByteBuf |
堆内存和直接内存
堆内存:多一次拷贝,需要从os 本地内存拷贝到Java的堆内存
磁盘-》os
os-》Java heap内存
数据需要 两次拷贝,效率较低

直接内存:零拷贝技术,只需要一次拷贝
池化 vs 非池化
池化的最大意义在于可以重用 ByteBuf,优点有
- 没有池化,则每次都得创建新的 ByteBuf 实例,这个操作对直接内存代价昂贵,就算是堆内存,也会增加 GC 压力
- 有了池化,则可以重用池中 ByteBuf 实例,并且采用了与 jemalloc 类似的内存分配算法提升分配效率
- 高并发时,池化功能更节约内存,减少内存溢出的可能
组成

write
writeByte,writeInt….
扩容规则
未超过512,下一个则是超过它的第一个16的整数倍
如果超过521,下一个则是超过它的第一个2的n次方数
read
readByte()
markReaderIndex() 标志
resetReaderIndex() 重置