日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Netty原理分析

發(fā)布時間:2023/12/9 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Netty原理分析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Netty是一個高性能、異步事件驅(qū)動的NIO框架,它提供了對TCP、UDP和文件傳輸?shù)闹С?#xff0c;作為一個異步NIO框架,Netty的所有IO操作都是異步非阻塞的,通過Future-Listener機制,用戶可以方便的主動獲取或者通過通知機制獲得IO操作結(jié)果。

作為當前最流行的NIO框架,Netty在互聯(lián)網(wǎng)領(lǐng)域、大數(shù)據(jù)分布式計算領(lǐng)域、游戲行業(yè)、通信行業(yè)等獲得了廣泛的應(yīng)用,一些業(yè)界著名的開源組件也基于Netty的NIO框架構(gòu)建。

Netty架構(gòu)分析

Netty 采用了比較典型的三層網(wǎng)絡(luò)架構(gòu)進行設(shè)計,邏輯架構(gòu)圖如下所示:

第一層:Reactor 通信調(diào)度層,它由一系列輔助類完成,包括 Reactor 線程 NioEventLoop 以及其父類、NioSocketChannel/NioServerSocketChannel 以及其父類、ByteBuffer 以及由其衍生出來的各種 Buffer、Unsafe 以及其衍生出的各種內(nèi)部類等。該層的主要職責(zé)就是監(jiān)聽網(wǎng)絡(luò)的讀寫和連接操作,負責(zé)將網(wǎng)絡(luò)層的數(shù)據(jù)讀取到內(nèi)存緩沖區(qū)中,然后觸發(fā)各種網(wǎng)絡(luò)事件,例如連接創(chuàng)建、連接激活、讀事件、寫事件等等,將這些事件觸發(fā)到 PipeLine 中,由 PipeLine 充當?shù)穆氊?zé)鏈來進行后續(xù)的處理。

第二層:職責(zé)鏈 PipeLine,它負責(zé)事件在職責(zé)鏈中的有序傳播,同時負責(zé)動態(tài)的編排職責(zé)鏈,職責(zé)鏈可以選擇監(jiān)聽和處理自己關(guān)心的事件,它可以攔截處理和向后/向前傳播事件,不同的應(yīng)用的 Handler 節(jié)點的功能也不同,通常情況下,往往會開發(fā)編解碼 Hanlder 用于消息的編解碼,它可以將外部的協(xié)議消息轉(zhuǎn)換成內(nèi)部的 POJO 對象,這樣上層業(yè)務(wù)側(cè)只需要關(guān)心處理業(yè)務(wù)邏輯即可,不需要感知底層的協(xié)議差異和線程模型差異,實現(xiàn)了架構(gòu)層面的分層隔離。

第三層:業(yè)務(wù)邏輯處理層,可以分為兩類:

1.純粹的業(yè)務(wù)邏輯處理,例如訂單處理。

2.應(yīng)用層協(xié)議管理,例如HTTP協(xié)議、FTP協(xié)議等。

接下來,我從影響通信性能的三個方面(I/O模型、線程調(diào)度模型、序列化方式)來談?wù)凬etty的架構(gòu)。

IO模型

Netty的I/O模型基于非阻塞I/O實現(xiàn),底層依賴的是JDK NIO框架的Selector。

Selector提供選擇已經(jīng)就緒的任務(wù)的能力。簡單來講,Selector會不斷地輪詢注冊在其上的Channel,如果某個Channel上面有新的TCP連接接入、讀和寫事件,這個Channel就處于就緒狀態(tài),會被Selector輪詢出來,然后通過SelectionKey可以獲取就緒Channel的集合,進行后續(xù)的I/O操作。

線程調(diào)度模型

常用的Reactor線程模型有三種,分別如下:

1.Reactor單線程模型:Reactor單線程模型,指的是所有的I/O操作都在同一個NIO線程上面完成。對于一些小容量應(yīng)用場景,可以使用單線程模型。

2.Reactor多線程模型:Rector多線程模型與單線程模型最大的區(qū)別就是有一組NIO線程處理I/O操作。主要用于高并發(fā)、大業(yè)務(wù)量場景。

3.主從Reactor多線程模型:主從Reactor線程模型的特點是服務(wù)端用于接收客戶端連接的不再是個1個單獨的NIO線程,而是一個獨立的NIO線程池。利用主從NIO線程模型,可以解決1個服務(wù)端監(jiān)聽線程無法有效處理所有客戶端連接的性能不足問題。

序列化方式

影響序列化性能的關(guān)鍵因素總結(jié)如下:

1.序列化后的碼流大小(網(wǎng)絡(luò)帶寬占用)

2.序列化&反序列化的性能(CPU資源占用)

3.并發(fā)調(diào)用的性能表現(xiàn):穩(wěn)定性、線性增長、偶現(xiàn)的時延毛刺等

鏈路有效性檢測

心跳檢測機制分為三個層面:

1.TCP層面的心跳檢測,即TCP的Keep-Alive機制,它的作用域是整個TCP協(xié)議棧;

2.協(xié)議層的心跳檢測,主要存在于長連接協(xié)議中。例如SMPP協(xié)議;

3.應(yīng)用層的心跳檢測,它主要由各業(yè)務(wù)產(chǎn)品通過約定方式定時給對方發(fā)送心跳消息實現(xiàn)。

心跳檢測的目的就是確認當前鏈路可用,對方活著并且能夠正常接收和發(fā)送消息。作為高可靠的NIO框架,Netty也提供了基于鏈路空閑的心跳檢測機制:

1.讀空閑,鏈路持續(xù)時間t沒有讀取到任何消息;

2.寫空閑,鏈路持續(xù)時間t沒有發(fā)送任何消息;

3.讀寫空閑,鏈路持續(xù)時間t沒有接收或者發(fā)送任何消息。

零拷貝

“零拷貝”是指計算機操作的過程中,?CPU不需要為數(shù)據(jù)在內(nèi)存之間的拷貝消耗資源?。而它通常是指計算機在網(wǎng)絡(luò)上發(fā)送文件時,不需要將文件內(nèi)容拷貝到用戶空間(User Space)而??直接在內(nèi)核空間(Kernel Space)中傳輸?shù)骄W(wǎng)絡(luò)的方式

Netty的“零拷貝”主要體現(xiàn)在三個方面

Netty的?接收和發(fā)送ByteBuffer采用DIRECT BUFFERS,使用堆外直接內(nèi)存進行Socket讀寫,不需要進行字節(jié)緩沖區(qū)的二次拷貝?。如果使用傳統(tǒng)的堆內(nèi)存(HEAP BUFFERS)進行Socket讀寫,JVM會將堆內(nèi)存Buffer拷貝一份到直接內(nèi)存中,然后才寫入Socket中。相比于堆外直接內(nèi)存,消息在發(fā)送過程中多了一次緩沖區(qū)的內(nèi)存拷貝

讀取直接從“堆外直接內(nèi)存”,不像傳統(tǒng)的堆內(nèi)存和直接內(nèi)存拷貝

ByteBufAllocator 通過ioBuffer分配堆外內(nèi)存

Netty提供了?組合Buffer對象?,可以聚合多個ByteBuffer對象,用戶可以??像操作一個Buffer那樣方便的對組合Buffer進行操作?,避免了傳統(tǒng)通過內(nèi)存拷貝的方式將幾個小Buffer合并成一個大的Buffer

Netty允許我們將多段數(shù)據(jù)合并為一整段虛擬數(shù)據(jù)供用戶使用,而過程中不需要對數(shù)據(jù)進行拷貝操作

組合Buffer對象,避免了內(nèi)存拷貝

ChannelBuffer接口:Netty為需要傳輸?shù)臄?shù)據(jù)制定了統(tǒng)一的ChannelBuffer接口

·???????使用getByte(int index)方法來實現(xiàn)隨機訪問

·???????使用雙指針的方式實現(xiàn)順序訪問

·???????Netty主要實現(xiàn)了HeapChannelBuffer,ByteBufferBackedChannelBuffer,與Zero Copy直接相關(guān)的CompositeChannelBuffer類

CompositeChannelBuffer類

CompositeChannelBuffer類的作用是將多個ChannelBuffer組成一個虛擬的ChannelBuffer來進行操作

為什么說是虛擬的呢,因為CompositeChannelBuffer并沒有將多個ChannelBuffer真正的組合起來,而只是保存了他們的引用,這樣就避免了數(shù)據(jù)的拷貝,實現(xiàn)了Zero Copy,內(nèi)部實現(xiàn)

其中readerIndex既讀指針和writerIndex既寫指針是從AbstractChannelBuffer繼承而來的

components是一個ChannelBuffer的數(shù)組,他保存了組成這個虛擬Buffer的所有子Buffer

indices是一個int類型的數(shù)組,它保存的是各個Buffer的索引值

lastAccessedComponentId是一個int值,它記錄了最后一次訪問時的子Buffer ID

CompositeChannelBuffer實際上就是將一系列的Buffer通過數(shù)組保存起來,然后實現(xiàn)了ChannelBuffer?的接口,使得在上層看來,操作這些Buffer就像是操作一個單獨的Buffer一樣

Netty的文件傳輸采用了?transferTo方法?,它可以直接將文件緩沖區(qū)的數(shù)據(jù)發(fā)送到目標Channel,避免了傳統(tǒng)通過循環(huán)write方式導(dǎo)致的內(nèi)存拷貝問題

Linux中的sendfile()以及Java NIO中的FileChannel.transferTo()方法都實現(xiàn)了零拷貝的功能,而在Netty中也通過在FileRegion中包裝了NIO的FileChannel.transferTo()方法實現(xiàn)了零拷貝

Netty 的 Zero-copy 體現(xiàn)在如下幾個個方面:

l? Netty 提供了 CompositeByteBuf 類, 它可以將多個 ByteBuf 合并為一個邏輯上的 ByteBuf, 避免了各個 ByteBuf 之間的拷貝。

l? 通過 wrap 操作, 我們可以將byte[] 數(shù)組、ByteBuf、ByteBuffer等包裝成一個 Netty ByteBuf 對象, 進而避免了拷貝操作。

l? ByteBuf 支持 slice 操作,因此可以將 ByteBuf 分解為多個共享同一個存儲區(qū)域的ByteBuf, 避免了內(nèi)存的拷貝。

l? 通過 FileRegion 包裝的FileChannel.tranferTo 實現(xiàn)文件傳輸, 可以直接將文件緩沖區(qū)的數(shù)據(jù)發(fā)送到目標 Channel, 避免了傳統(tǒng)通過循環(huán) write 方式導(dǎo)致的內(nèi)存拷貝問題。

轉(zhuǎn)載于:https://www.cnblogs.com/lfs2640666960/p/10010011.html

總結(jié)

以上是生活随笔為你收集整理的Netty原理分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。