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次,防止一個線程一直佔據流量。