為什麼Netty執行緒池預設大小為CPU核數的2倍

語言: CN / TW / HK

有位工作5年的小夥伴問我說,為什麼Netty執行緒池預設大小為CPU核數的2倍,今天,我花2分鐘時間給大家專門分享一下我對這個問題的理解。

另外,我花了1個多星期把往期的面試題解析配套文件準備好了,想獲取的小夥伴可以關注我的煮葉介紹!

1、分析原因

我們都知道使用多執行緒的本質是為了提升程式的效能,總體來說有兩個最核心的指標,一個延遲,一個吞吐量。延遲指的是發出請求到收到響應的時間,吞吐量指的是 。這兩個指標之間有一定的關聯,因為同等條件下延遲越短吞吐量越大,但由於它們是不同的維度,一個是時間,一個是空間,並不能相互轉換。

因此,提升效能最主要的目的就是要降低延遲,提高吞吐量。

那我們如何來衡量這些效能指標呢?

2、如何衡量效能指標

具體來說,要降低延時,就是要提高CPU的處理能力。而提高吞吐量,就是要提高IO讀寫效率。那麼具體如何衡量系統性能,我從以下兩個方面來分析:

我們可以將程式分為是I/O密集型任務和CPU密集型任務。

那麼第1種情況,對於CPU密集型任務而言,理論上“執行緒的數量 = CPU核數”就是合適的。但是,在實際應用中的執行緒數量一般會設定為“CPU核數 + 1”。因為執行緒有可能因為記憶體頁失效或其他原因導致阻塞,多設定一個執行緒可以保證CPU的利用率。\

第2種情況,而對於I/O密集型任務而言,我們假設CPU計算和I/O操作的耗時比是 1:1,那麼2個執行緒是最合適的。如果CPU計算和I/O操作的耗時比是 1:2,也就是說3個執行緒是合適的,這樣CPU和I/O裝置的利用率都可以達到100%。根據這個推測,我們可以得到這樣一個公式:

最佳執行緒數 = 1 +(IO耗時/CPU耗時)

不過上面這個公式是針對單核CPU,如果是多核CPU只需要等比擴大就可以了,假設IO耗時和CPU耗時比為R,那麼計算公式如下:

最佳執行緒數 = CPU核數 *(1 + R)

而Netty的預設執行緒池個數,就是假設了I/O耗時和CPU耗時的佔比是1:1,實際上Netty有一個引數叫ioRatio,預設為50,它表示在一個輪事件迴圈中,單個I/O執行緒執行I/O事件和執行非同步任務的耗時佔比為 1:1。相當於 R = 1,代入上面的公式,就可以得出Netty預設設定的執行緒池大小自然就是 

預設執行緒池大小 = CPU核數 * (1 + 1)

也就2倍CPU核數大小。而且Netty的應用場景主要是I/O密集型任務,所以,Netty這樣設計是有科學性的。

看到了這裡,你是不是豁然開朗了呢?

3、總結與使用建議

通過前面的分析,我們已經知道了Netty執行緒池預設大小未CPU核數2倍的原因,我們在實際開發中,如何來得到一個比較準確的執行緒池大小呢?

我們可以提前壓測,根據壓測結果來進行微調。一般情況下,保證生產環境為壓測環境的75%即可。如果修改Netty的執行緒池大小,也一定要考慮ioRatio這個引數是否需要調整,因為2倍CPU核數的大小是假設的I/O耗時和CPU耗時為1:1,調整執行緒大小之後,效能效果也不一定符合期望值。

在大部分場景下,沒有必要太過於關注執行緒池大小怎麼配置,I/O密集型任務使用Netty預設配置就可以了。因為,提高吞吐量也不能只簡單的只依賴執行緒池,還可以通過快取、微服務拆分,優化業務邏輯、優化演算法等方式來協作解決。

好了,以上就是我的分享和理解,對望能對大家有所幫助。我是被程式設計耽誤的文藝Tom,如果我的分享對你有幫助,請動動手指一鍵三連分享給更多的人。關注我,面試不再難!

本文為“Tom彈架構”原創,轉載請註明出處。技術在於分享,我分享我快樂!\ 如果本文對您有幫助,歡迎關注和點贊;如果您有任何建議也可留言評論或私信,您的支援是我堅持創作的動力。 關注微信公眾號『 Tom彈架構 』回覆“666”可獲取200頁的PDF面試文件!

我是被程式設計耽誤的文藝Tom