多線程,到底該設置多少個線程?

做者:享學課堂老顧數據庫

微信公衆號: 享學課堂online後端

在這裏插入圖片描述

1、前言

「很差了,線上服務器超時嚴重,請求很是慢,好像報鏈接數too many了,怎麼辦?「小夥伴們在反饋。通常咱們的技術老大的處理方式,把鏈接數和線程池調大點,重啓,再觀察。服務器

每每這個方式是應急措施,治標不治本,由於不知道問題的緣由。微信

有個嚴重誤區,覺得線程池設置過小了,調大點請求就會快了。網絡

今天就帶着小夥伴們溝通一下,線程池的大小應該如何合理的設置其大小?多線程

2、問題

若是有兩個任務須要處理,一個任務A,一個任務B架構

方案一:一個線程執行任務A和B,A執行完後,執行B 方案二:兩個線程A和B去執行任務A 和 B,同時進行併發

哪一個方案會快點?應該不少人會回答,確定是方案二啊,多線程並行去處理任務A和B,確定快啊。是這樣嗎?回答這個問題以前,先帶着你們去回顧梳理一下。分佈式

3、線程執行

線程的執行,是由CPU進行調度的,一個CPU在同一時刻只會執行一個線程,咱們看上去的線程A 和 線程B併發執行。微服務

爲了讓用戶感受這些任務正在同時進行,操做系統利用了時間片輪轉的方式,CPU給每一個任務都服務必定的時間,而後把當前任務的狀態保存下來,在加載下一任務的狀態後,繼續服務下一任務。任務的狀態保存及再加載,這段過程就叫作上下文切換。

上下文切換過程是須要時間的;如今咱們來看一下上面的問題,小夥伴們再看一下是哪一個方案快呢?是否是有些小夥伴們會說方案一,由於不須要線程切換;方案二須要來回切換這兩個線程,耗時會多點。

小夥伴們心中此時是否是會有疑惑,那爲何會有多線程?先不急,再往下看。

4、爲何要多線程

小夥伴想一想在咱們真實業務中,咱們是什麼流程?

在這裏插入圖片描述

上圖的流程:

一、先發起網絡請求

二、Web服務器解析請求

三、請求後端的數據庫獲取數據

四、獲取數據後,進行處理

五、把處理結果放回給用戶

這個是咱們處理業務的時候,常規的請求流程;咱們看一下整個過程涉及到什麼計算機處理。

一、網絡請求----->網絡IO

二、解析請求----->CPU

三、請求數據庫----->網絡IO

四、MySQL查詢數據----->磁盤IO

五、MySQL返回數據----->網絡IO

六、數據處理----->CPU

七、返回數據給用戶----->網絡IO

講到這裏,小夥伴們是否是感受又不亂了,在真實業務中咱們不僅僅會涉及CPU計算,還有網絡IO和磁盤IO處理,這些處理是很是耗時的。若是一個線程整個流程是上圖的流程,真正涉及到CPU的只有2個節點,其餘的節點都是IO處理,那麼線程在作IO處理的時候,CPU就空閒出來了,CPU的利用率就不高。

小夥伴們如今知道多線程的用處了吧,對,就是爲了提高CPU利用率。

5、提高QPS/TPS

衡量系統性能如何,主要指標系統的(QPS/TPS)

QPS/TPS:每秒可以處理請求/事務的數量

併發數:系統同時處理的請求/事務的數量

響應時間:就是平均處理一個請求/事務須要時長

QPS/TPS = 併發數/響應時間

上面公式表明併發數越大,QPS就越大;因此不少人就會覺得調大線程池,併發數就會大,也會提高QPS,因此纔會出現一開始前言所說的,大多數人的誤區。

其實QPS還跟響應時間成反比,響應時間越大,QPS就會越小。

雖然併發數調大了,就會提高QPS,但線程數也會影響響應時間,由於上面咱們也提到了上下文切換的問題,那怎麼設置線程數的呢?

6、如何設置線程數

那咱們如何分配線程?咱們提供一個公式:

最佳線程數目 = ((線程等待時間+線程CPU時間)/線程CPU時間 )* CPU數目

備註這個公式也是前輩們分享的,固然以前看了淘寶前臺系統優化實踐的文章,和上面的公式很相似,不過在CPU數目那邊,他們更細化了,上面的公式只是參考。不過無論什麼公式,最終仍是在生產環境中運行後,再優化調整。

咱們繼續上面的任務,咱們的服務器CPU核數爲4核,一個任務線程cpu耗時爲20ms,線程等待(網絡IO、磁盤IO)耗時80ms,那最佳線程數目:( 80 + 20 )/20 * 4 = 20。也就是設置20個線程數最佳。

從這個公式上面咱們就得出,線程的等待時間越大,線程數就要設置越大,這個正好符合咱們上面的分析,可提高CPU利用率。那從另外一個角度上面說,線程數設置多大,是根據咱們自身的業務的,須要本身去壓力測試,設置一個合理的數值。

7、基礎常規標準

那咱們小夥伴們會問,由於不少業務集中到一個線程池中,不像上面的案例比較簡單,事實上業務太多,怎麼設置呢?這個就是要去壓力測試去調整。不過咱們的前輩已經幫咱們總結了一個基礎的值(最終仍是要看運行狀況自行調整)

一、CPU密集型:操做內存處理的業務,通常線程數設置爲:CPU核數 + 1 或者 CPU核數*2。核數爲4的話,通常設置 5 或 8

二、IO密集型:文件操做,網絡操做,數據庫操做,通常線程設置爲:cpu核數 / (1-0.9),核數爲4的話,通常設置 40

8、總結

今天介紹了線程數大小的設置,一些小夥伴們的誤區。講到這裏咱們小夥伴們是否是對線程有了更新的理解,不像以前那麼粗暴,應該要去分析爲何這麼慢,系統的瓶頸出如今什麼地方,減小瓶頸的耗時。

另外,推薦小夥伴們再去看一下Redis、Nginx;爲何他們會那麼快呢?其實和這篇文章的知識點有共同的地方。

熱門內容:

一、系統又出Bug?這幾個調優攻略,幫你解決大部分問題!

二、生產環境下到底該如何部署Tomcat?

三、神級代碼註釋鑑賞,喜歡就拿去用!

四、開源的13個Spring Boot 優秀學習項目!超53K星,一網打盡!

五、華爲海思總裁致員工信:再也不有換胎機會,必當科技自立!

六、不瞭解這12個語法糖,別說你會Java!

七、小小的分頁問題引起的加班血案!

八、1萬屬性,100億數據,每秒10萬吞吐,架構如何設計?

在這裏插入圖片描述

【視頻福利】2T免費學習視頻,搜索或掃描上述二維碼關注微信公衆號:Java後端技術(ID: JavaITWork),和20萬人一塊兒學Java!回覆:1024,便可免費獲取!內含SSM、Spring全家桶、微服務、MySQL、MyCat、集羣、分佈式、中間件、Linux、網絡、多線程,Jenkins、Nexus、Docker、ELK等等免費學習視頻,持續更新!

相關文章
相關標籤/搜索