1

Netty基本介绍,参考 https://juejin.cn/post/7408844429370834954

1 Netty读事件

1.1 READ事件,NioEventLoop#processSelectedKey在第二次循环的时候就是读事件

现在unsafe类不一样,NioSocketChannel$NioSocketChannelUnsafe类,进入Read方法,我们进入了AbstarctNioByteChannel <---继承自---NioSocketChannel

2.2 AbstractNioByteChannel.NioByteUnsafe#read

读取数据流程
1.进入read()方法,先申请一个byteBuf,初始容量2048,然后循环读取数据
2.记录读了多少,根据读取对buffer情况扩容缩容
3.allocHandle.incMessagesRead(1); 每次读取数据会讲次数+1
4.pipeline.fireChannelRead(byteBuf); 执行读取逻辑
5.判断是否继续
下面我们分析下该流程里面的关键步骤

2.3 buffer容量分配,进入allocate方法,有一个guess获取容量

2.4 扩容缩容,进入allocHandle.lastBytesRead

该方法可以对buffer进行扩容缩容,进入record方法

2.5 扩容缩容,AdaptiveRecvByteBufAllocator.HandleImpl#record

如下图,该方法通过两次判断决定是否扩容,decreaseNow第一次判断成功后会被复制为true,第二次判断通过后,如果decreaseNow是true,说明上一次也是判断通过,可以缩容。

2.6 继续循环判断,接着我们看while循环的判断条件 allocHandle.continueReading()

进入该方法,totalMessages是循环读取次数,每循环一次加1,maxMessagePerRead=16,这里表示最大允许循环16读取,防止一个线程一直读,给其他线程让出机会。

总结:

Netty对NIO的读数据改进:

1、读数据通过自适应buffer来读取,根据读取数据的大小调整buffer大小,加快读取速度

2、控制每个NioEventLoop读取最大循环16次,防止一个线程一直占据流量。


杜若
70 声望3 粉丝