現象
某個應用,機器數增加到了150臺,但是發現其load較高。
對於4核機器來說,負載率高峯期超過4,意味着高峯期幾乎滿載,這是一個不正常的現象。
經驗法則如下: 當系統負荷持續大於0.7,你必須開始調查了,問題出在哪裏,防止情況惡化; 當系統負荷持續大於1.0,你必須動手尋找解決辦法,把這個值降下來; 當系統負荷達到5.0,就表明你的系統有很嚴重的問題,長時間沒有響應或者接近死機了。
指標
首先確認系統無FullGC、Java線程符合預期。
查看CPU,CPU一直運行在較高的峯值。當然對於4核CPU來說,這個比例就不算太高。
分析
那麼我們分析出來了比較明顯的結論,CPU運行低和LOAD較高,則表示等待IO的進程比較多。我們進一步定位問題,我們DUMP線程,看看線程在等待什麼了,爲什麼會導致如此高的IO。
sudo /opt/taobao/java/bin/jstack -F 1908 > stack.log
經過統計,發現大量的線程都BLOCKED在紅色的代碼代碼內,那麼這段代碼到底是做了什麼,爲什麼會BLOCK大量的請求。
繼續使用線程診斷,發現大量的線程都在等待狀態,其中等待的代碼段是logback的日誌打印。
根據業務情況,我們就得到了結論,即本系統有大量線程的相同代碼塊同步打印同一個日誌,導致加鎖並行處理,進而導致多個沒有取到鎖的線程在等待上個線上打印日誌釋放資源。
優化
很簡單的一個辦法,就是利用Logback的異步打印日誌,可以參考文檔:
https://examples.javacodegeeks.com/enterprise-java/logback/logback-ayncappender-example/
核心原理是同步打印日誌是直接對文件同步操作,而異步打印日誌原理就是打印日誌寫將日誌寫到隊列,然後將隊列異步寫到文件裏去。
結果
優化後,發佈線上觀察機器的LOAD情況如下:
可以看到,發佈優化後的LOAD已經小於昨日的同比LOAD,說明優化還是有一定的效果的。但是,同時發現,優化不明顯,說明還有其他原因,還需要進一步排查是否有其他系統未知問題。
思考
系統調優是難度非常大的一個課題,也是需要具備非常深的基礎底層知識,才能更快的定位和分析以及解決問題。