享學課堂特邀做者:老顧
「很差了,線上服務器超時嚴重,請求很是慢,好像報鏈接數too many了,怎麼辦?「小夥伴們在反饋。通常咱們的技術老大的處理方式,把鏈接數和線程池調大點,重啓,在觀察。
每每這個方式是應急措施,治標不治本,由於不知道問題的緣由。
有個嚴重誤區,覺得線程池設置過小了,調大點請求就會快了。
今天老顧就帶着小夥伴們溝通一下,線程池的大小應該如何合理的設置其大小?mysql
若是有兩個任務須要處理,一個任務A,一個任務Bnginx
方案一:一個線程執行任務A和B,A執行完後,執行B
方案二:兩個線程A和B去執行任務A 和 B,同時進行
複製代碼
哪一個方案會快點?應該不少人會回答,確定是方案二啊,多線程並行去處理任務A和B,確定快啊。是這樣嗎?回答這個問題以前,先帶着你們去回顧梳理一下。web
多線程的執行,是由CPU進行調度的,一個CPU在同一時刻只會執行一個線程,咱們看上去的線程A 和 線程B併發執行,爲了讓用戶感受這些任務正在同時進行,操做系統利用了時間片輪轉的方式,CPU給每一個任務都服務必定的時間,而後把當前任務的狀態保存下來,在加載下一任務的狀態後,繼續服務下一任務。任務的狀態保存及再加載,這段過程就叫作上下文切換。redis
上下文切換的過程是須要時間的;如今咱們再來看一下上面的問題,咱們小夥伴們再看一下是哪一個方案快呢?是否是有些小夥伴們會說方案一,由於不須要線程切換。先不急,再往下看sql
按照上面的說法,有線程的上下文切換耗時,那麼爲何須要多線程呢?小夥伴會不會感受很亂,怎麼回事?
小夥伴想一想在咱們真實業務中,咱們是什麼流程?
數據庫
上圖的流程:後端
一、先發起網絡請求
二、web服務器解析請求
三、請求後端的數據庫獲取數據
四、獲取數據後,進行處理
五、把處理結果放回給用戶服務器
這個是咱們處理業務的時候,常規的請求流程;咱們看一下整個過程涉及到什麼計算機處理。網絡
一、網絡請求----->網絡IO
二、解析請求----->CPU
三、請求數據庫----->網絡IO
四、mysql查詢數據----->磁盤IO
五、mysql返回數據----->網絡IO
六、數據處理----->CPU
七、返回數據給用戶----->網絡IO多線程
小夥伴們是否是感受又不亂了,在真實業務中咱們不僅僅會涉及cpu計算,還有網絡IO和磁盤IO處理,這些處理是很是耗時的。若是一個線程整個流程是上圖的流程,真正涉及到CPU的只有2個節點,其餘的節點都是IO處理,那麼線程在作IO處理的時候,CPU就空閒出來了,CPU的利用率就不高。
小夥伴們如今知道多線程的用處了吧,對,就是爲了提高CPU利用率。
衡量系統性能如何,主要指標系統的(QPS/TPS)。
QPS/TPS:每秒可以處理請求/事務的數量
併發數:系統同時處理的請求/事務的數量
響應時間:就是平均處理一個請求/事務須要時長
QPS/TPS = 併發數/響應時間
複製代碼
也就是併發數越大,QPS就越大;因此不少人就會覺得調大線程池,併發數就會大,也會提高QPS,因此纔會出現一開始前言所說的。其實QPS還跟響應時間成反比,響應時間越大,QPS就會越小。
雖然併發數調大了,就會提高QPS,但線程數也會影響響應時間,由於上面咱們也提到了上下文切換的問題,那怎麼設置線程數的呢?
那咱們如何分配線程?咱們提供一個公式:
最佳線程數目 = ((線程等待時間+線程CPU時間)/線程CPU時間 )* CPU數目
複製代碼
備註這個公式也是前輩們分享的,固然老顧看了淘寶前臺系統優化實踐的文章,和上面的公式很相似,不過在CPU數目那邊,他們更細化了,不過無論什麼公式,最終仍是在生產環境中運行後,再優化調整。
咱們繼續上面的任務,咱們的服務器CPU核數爲4核,一個任務線程cpu耗時爲20ms,線程等待(網絡IO、磁盤IO)耗時80ms,那最佳線程數目:( 80 + 20 )/20 * 4 = 20。也就是設置20個線程數最佳。
從這個公式上面咱們就得出,線程的等待時間越大,線程數就要設置越大,這個正好符合咱們上面的分析,充分利用cpu利用率。那從另外一個角度上面說,線程數設置多大,是根據咱們自身的業務的,須要本身去壓力測試,設置一個合理的數值。
那咱們小夥伴們會問,由於不少業務集中到一個線程池中,不像上面的案例比較簡單,事實上業務太多,怎麼設置呢?這個就是要去壓力測試去調整。不過咱們的前輩已經幫咱們總結了一個基礎的值(最終仍是要看運行狀況自行調整)
CPU密集型:操做內存處理的業務,通常線程數設置爲:CPU數 + 1或者 CPU數*2。核數爲4的話,通常設置 5 或 8
IO密集型:文件操做,網絡操做,數據庫操做,通常線程設置爲:cpu數 / (1-0.9),數爲4的話,通常設置 40
今天介紹了線程數大小的設置,一些小夥伴們的誤區。講到這裏咱們小夥伴們是否是對線程有了更新的理解,不像以前那麼粗暴,應該要去分析爲何這麼慢,系統的瓶頸出如今什麼地方,減小瓶頸的耗時。
老顧能夠推薦小夥伴們再去看一下redis、nginx;爲何他們會那麼快呢?其實和這篇文章的知識點有共同的地方。謝謝閱讀!!!
歡迎你們在下面評論留言,後面還會持續更新更多精選文章分享,同時能夠關注下官方公衆號,天天都會有許多精選分享及不按期福利學習資料免費領取!