Netty------爲什麼Netty性能如此之高?

Netty高性能之道

目錄

Netty高性能之道

1、Netty模型

2、Netty性能高的原因


1、Netty模型

netty線程模型採用“服務端監聽線程”和“IO線程”分離的方式,與多線程Reactor模型類似。

抽象出NioEventLoop來表示一個不斷循環執行處理任務的線程,每個NioEventLoop有一個selector,用於監聽綁定在其上的socket鏈路。

說明:

1) Netty抽象出兩組線程池 BossGroup專門負責接收客戶端的連接, Worker Group專門負責網絡的讀寫

2) Boss Group和 Worker Group類型都是 NioEventLoopGroup

3) NioEventLoop Giroup相當於一個事件循環組,這個組中含有多個事件循環,每一個事件循環是 NioEventLoop

4) NioEventLoop表示一個不斷循環的執行處理任務的線程,每個 NioEventLoop都有一個 selector,用於監聽綁定在其上的 socket的網絡通訊

5) NioEventLoop Group可以有多個線程,即可以含有多個 NioE:ventLoop

6)每個 Boss NioEventLoop循環執行的步驟有3步

  1.輪詢 accept事件

  2.處理 accept事件,與 client建立連接,生成 NioScocketchannel,並將其註冊到某個 worker NIOEventLoop上的 selector

  3.處理任務隊列的任務,即 runAllTasks

7)每個 Worker NIOEventLoop循環執行的步驟

   1.輪詢read, write事件

   2.處理0事件,即ead,wite事件,在對應 NioScocketChannel處理

   3.處理任務隊列的任務,即 runAlllask

8)每個 Worker NIOE ventloop處理業務時,會使用 pipeline管道, pipeline中包含了 channel,即通過 pipeline可以獲取到對應通道,管道中維護了很多的處理器

2、Netty性能高的原因

  • 非阻塞IO

    Netty採用了IO多路複用技術,讓多個IO的阻塞複用到一個select線程阻塞上,能夠有效的應對大量的併發請求

  • 高效的Reactor線程模型

    Netty服務端採用Reactor主從多線程模型

    1. 主線程:Acceptor 線程池用於監聽Client 的TCP 連接請求

    2. 從線程:Client 的IO 操作都由一個特定的NIO 線程池負責,負責消息的讀取、解碼、編碼和發送

    3. Client連接有很多,但是NIO 線程數是比較少的,一個NIO 線程可以同時綁定到多個Client,同時一個Client只能對應一個線程,避免出現線程安全問題

  • 無鎖化串行設計

    串行設計:消息的處理儘可能在一個線程內完成,期間不進行線程切換,避免了多線程競爭和同步鎖的使用

  • 高效的併發編程

    Netty 的高效併發編程主要體現在如下幾點

    1. volatile 的大量、正確使用

    2. CAS 和原子類的廣泛使用

    3. 線程安全容器的使用

    4. 通過讀寫鎖提升併發性能

  • 高性能的序列化框架

    Netty 默認提供了對Google Protobuf 的支持,通過擴展Netty 的編解碼接口,可以實現其它的高性能序列化框架

  • 零拷貝

    1. Netty 的接收和發送ByteBuffer 採用DirectByteBuffer,使用堆外直接內存進行Socket 讀寫,不需要進行字節緩衝區的二次拷貝。如果使用傳統的堆內存(HeapByteBuffer)進行Socket 讀寫,JVM 會將堆內存Buffer 拷貝一份到直接內存中,然後才寫入Socket 中。相比於堆外直接內存,消息在發送過程中多了一次緩衝區的內存拷貝

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

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

  • 內存池

    基於對象池的 ByteBuf可以重用 ByteBuf對象,內部維護了一個內存池,可以循環利用已創建的 ByteBuf,提升內存的使用效率,降低由於高負載導致的頻繁GC。測試表明使用內存池後的Nety在高負載、大併發的衝擊下內存和GC更加平穩

  • 靈活的TCP 參數配置能力

    合理設置TCP 參數在某些場景下對於性能的提升可以起到顯著的效果,例如SO_RCVBUF 和SO_SNDBUF。如果設置不當,對性能的影響是非常大的

    1. SO_RCVBUF 和SO_SNDBUF:通常建議值爲128K 或者256K;

    2. SO_TCPNODELAY:NAGLE 算法通過將緩衝區內的小封包自動相連,組成較大的封包,阻止大量小封包的發送阻塞網絡,從而提高網絡應用效率。但是對於時延敏感的應用場景需要關閉該優化算法;

    3. 軟中斷:如果Linux 內核版本支持RPS(2.6.35 以上版本),開啓RPS 後可以實現軟中斷,提升網絡吞吐量。RPS根據數據包的源地址,目的地址以及目的和源端口,計算出一個hash 值,然後根據這個hash 值來選擇軟中斷運行的cpu,從上層來看,也就是說將每個連接和cpu 綁定,並通過這個hash 值,來均衡軟中斷在多個cpu 上,提升網絡並行處理性能

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章