中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Netty原理分析往這邊看!

發布時間:2020-08-09 02:51:31 來源:ITPUB博客 閱讀:146 作者:Java大蝸牛 欄目:編程語言

Netty原理分析往這邊看!

 

Netty是一個高性能、異步事件驅動的NIO框架,它提供了對TCP、UDP和文件傳輸的支持,作為一個異步NIO框架,Netty的所有IO操作都是異步非阻塞的,通過Future-Listener機制,用戶可以方便的主動獲取或者通過通知機制獲得IO操作結果。

作為當前最流行的NIO框架,Netty在互聯網領域、大數據分布式計算領域、游戲行業、通信行業等獲得了廣泛的應用,一些業界著名的開源組件也基于Netty的NIO框架構建。

Netty架構分析

Netty 采用了比較典型的三層網絡架構進行設計,邏輯架構圖如下所示:

Netty原理分析往這邊看!

 

第一層:Reactor 通信調度層,它由一系列輔助類完成,包括 Reactor 線程 NioEventLoop 以及其父類、NioSocketChannel/NioServerSocketChannel 以及其父類、ByteBuffer 以及由其衍生出來的各種 Buffer、Unsafe 以及其衍生出的各種內部類等。該層的主要職責就是監聽網絡的讀寫和連接操作,負責將網絡層的數據讀取到內存緩沖區中,然后觸發各種網絡事件,例如連接創建、連接激活、讀事件、寫事件等等,將這些事件觸發到 PipeLine 中,由 PipeLine 充當的職責鏈來進行后續的處理。

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

第三層:業務邏輯處理層,可以分為兩類:

1.純粹的業務邏輯處理,例如訂單處理。

2.應用層協議管理,例如HTTP協議、FTP協議等。

接下來,我從影響通信性能的三個方面(I/O模型、線程調度模型、序列化方式)來談談Netty的架構。

這里推薦一下我的Java架構學習群:479499375 ,群里有(Java高架構、分布式架構、高可擴展、高性能、高并發、性能優化、Spring boot、Redis、ActiveMQ、等學習資源)進群免費送給每一位Java小伙伴,不管你是轉行,還是工作中想提升自己能力都可以!

IO模型

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

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

線程調度模型

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

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

Netty原理分析往這邊看!

 

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

Netty原理分析往這邊看!

 

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

Netty原理分析往這邊看!

 

序列化方式

影響序列化性能的關鍵因素總結如下:

1.序列化后的碼流大小(網絡帶寬占用)

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

3.并發調用的性能表現:穩定性、線性增長、偶現的時延毛刺等

這里推薦一下我的Java架構學習群:479499375 ,群里有(Java高架構、分布式架構、高可擴展、高性能、高并發、性能優化、Spring boot、Redis、ActiveMQ、等學習資源)進群免費送給每一位Java小伙伴,不管你是轉行,還是工作中想提升自己能力都可以!

鏈路有效性檢測

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

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

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

3.應用層的心跳檢測,它主要由各業務產品通過約定方式定時給對方發送心跳消息實現。

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

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

2.寫空閑,鏈路持續時間t沒有發送任何消息;

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

零拷貝

  • “零拷貝”是指計算機操作的過程中,  CPU不需要為數據在內存之間的拷貝消耗資源 。而它通常是指計算機在網絡上發送文件時,不需要將文件內容拷貝到用戶空間(User Space)而  直接在內核空間(Kernel Space)中傳輸到網絡的方式

  • Netty的“零拷貝”主要體現在三個方面

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

  • 讀取直接從“堆外直接內存”,不像傳統的堆內存和直接內存拷貝

  • ByteBufAllocator 通過ioBuffer分配堆外內存

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

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

  • 組合Buffer對象,避免了內存拷貝

  • ChannelBuffer接口:Netty為需要傳輸的數據制定了統一的ChannelBuffer接口

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

· 使用雙指針的方式實現順序訪問

· Netty主要實現了HeapChannelBuffer,ByteBufferBackedChannelBuffer,與Zero Copy直接相關的CompositeChannelBuffer類

  • CompositeChannelBuffer類

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

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

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

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

  • indices是一個int類型的數組,它保存的是各個Buffer的索引值

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

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

  • Netty的文件傳輸采用了  transferTo方法  ,它可以直接將文件緩沖區的數據發送到目標Channel,避免了傳統通過循環write方式導致的內存拷貝問題

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

Netty 的 Zero-copy 體現在如下幾個個方面:

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

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

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

l 通過 FileRegion 包裝的FileChannel.tranferTo 實現文件傳輸, 可以直接將文件緩沖區的數據發送到目標 Channel, 避免了傳統通過循環 write 方式導致的內存拷貝問題。


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

定襄县| 九寨沟县| 蓬安县| 保山市| 嘉黎县| 宜宾市| 翁源县| 阿坝县| 镇坪县| 辰溪县| 安福县| 濮阳市| 垦利县| 正蓝旗| 晴隆县| 七台河市| 健康| 桐城市| 台中县| 怀仁县| 诸城市| 顺平县| 岱山县| 开封市| 平顺县| 濉溪县| 普兰店市| 靖安县| 含山县| 西安市| 渭源县| 阿瓦提县| 忻州市| SHOW| 称多县| 博湖县| 赫章县| 江永县| 嘉荫县| 施秉县| 河间市|