cpu消耗過高的問題

類似:
2、開了一個飯店,客人多,服務員很忙,就很正常
2、開了一個飯店,客人很少,但是服務員每個人都很繁忙,這種現象不正常
壓測場景:
30個線程


發現CPU已經很高了,使用占到99%了
這個時候我們提高線程到40,由於CPU已經到99%,再怎么提高線程,壓測后其實TPS沒有多大效果提升,響應時間可能會漲
說明你的瓶頸就是CPU,CPU降下來,TPS肯定會上升
我們首先要看哪個進程占的cpu高(我們壓的是tomcat,所以不能有別的進程占CPU高,沒有別的項目影響我們)
top --查看cpu哪個進程高
用工具定位CPU,分析問題

線程死鎖,阻塞都是可以通過這個軟件看見的jprofiler
我們必須要有2個端,Linux + window (因為自己用的是wind) 需要將他們聯系起來
linux 安裝 jprofiler
解壓:tar -zxvf jprofiler_linux_11_1_4.tar.gz
進入解壓目錄: cd jprofiler11.1.4/
運行: bin/jprofiler
3、安裝完成運行
http://pan.baidu.com/s/1gfBJ0kV
jprofiler_linux_9_2.sh
chmod +x jprofiler_linux_9_2.sh
我這里的路徑是:
/opt/jprofiler9/bin/linux-x86/libjprofilerti.so
需要添加參數(tomcat啟動,添加到tomcat,別的服務啟動,就添加到對應的啟動服務里)


安裝window 客戶端的jprofiler
keyGen.exe去找key

連接服務器的CPU




遠程連接地址:



然后點OK
連不上,可能是防火牆的原因或者是tomcat原因
下面表示連接上了


重新開始壓測:
觀看jprofile誰占的cpu是最高的

Gjson占了57% 被調用5849980次
再看看其他數據

CPU很忙,但是60%花在了Gjson上了

此時,響應時間少,吞吐量達到290
此時,現在不用Gjosn,重新壓測看看



發現TPS達到了9百多,並且CPU還沒達到90,說明還可以加線程,往下壓測,性能得到了明顯得改善!TPS翻了4倍!
總結:

響應時間長:

不消化cpu,而且響應時間很慢
看nginx和tomcat日志,看響應時間,縮小范圍
20並發:


cpu只用了%10不到,但是響應時間卻耗時400多毫秒左右(剛才壓得時候是20多),明顯有問題,看GC也沒問題

可以用jprofile去看 看,因為tps比較低,響應時間長,這個時候就可以用jporfile,因為你現在已經就很低了

結果就一目樂然了,這個方法占時很多,一半先看total順序,然后再去看Media time 中位數
我們還可以看看call tree ,結合去看,到底誰調用它了,它調用了誰了

再回過頭來看看 method static

我們看看源碼就知道為什么具體這么慢了。。


數據庫性能問題 - 慢查詢:
見pdf,已經寫的很詳細了

壓測案例:
dstat -tcmnd --disk-util 監控服務器 (正常)

jmeter 監控情況:
數據庫所在服務器:

cpu很高很高,很明顯這是有問題 的。。。我們怎么排查呢?

sql 監控就是慢查詢的pdf 方法
/etc/my.cnf

重啟Mysql

慢查詢日志,最好在這個路徑下,因為寫在別的路徑下,可能Mysql沒有讀寫權限!
/var/lib/mysql/slow.log
數據庫去查詢這個sql語句。
1、首先找出比較大得sql語句,然后用explain分析一下
2、然后再通過工具看這個表得索引情況,入下圖:


type 解釋:


圖上type類型,由上往下,性能越來越低
type:ALL 沒加索引,全表掃描,像新華字典一樣,一頁一頁往后翻
聯合索引:
命名規則:表名_字段名
1、需要加索引的字段,要在where條件中
2、數據量少的字段不需要加索引
3、如果where條件中是OR關系,加索引不起作用
4、符合最左原則
https://segmentfault.com/q/1010000003984016/a-1020000003984281
聯合索引又叫復合索引。對於復合索引:Mysql從左到右的使用索引中的字段,一個查詢可以只使用索引中的一部份,但只能是最左側部分。例如索引是key index (a,b,c). 可以支持a | a,b| a,b,c 3種組合進行查找,但不支持 b,c進行查找 .當最左側字段是常量引用時,索引就十分有效。
兩個或更多個列上的索引被稱作復合索引。
利用索引中的附加列,您可以縮小搜索的范圍,但使用一個具有兩列的索引 不同於使用兩個單獨的索引。
復合索引的結構與電話簿類似,人名由姓和名構成,電話簿首先按姓氏對進行排序,然后按名字對有相同姓氏的人進行排序。
如果您知 道姓,電話簿將非常有用;
如果您知道姓和名,電話簿則更為有用,
但如果您只知道名不姓,電話簿將沒有用處。
所以說創建復合索引時,應該仔細考慮列的順序。對索引中的所有列執行搜索或僅對前幾列執行搜索時,復合索引非常有用;僅對后面的任意列執行搜索時,復合索引則沒有用處。
http://blog.csdn.net/lmh12506/article/details/8879916



重新壓測:
cpu正常,TPS低,響應時間短


數據庫性能:連接數
案例:
先用10個線程去壓測接口:


CPU 沒達到90多以上!吞吐量437左右
我們再用20個線程去壓看看,因為CPU還沒到極限,所以我們繼續往下壓得話,TPS一定會增長


我們發現CPU還是沒有用完,TPS增長緩慢,到達545
我們再用30個線程去壓試試看:


CPU只用到了80左右,TPS同樣增長緩慢
40個線程去壓:


CPU只用到了80左右,TPS同樣增長緩慢,達到641
用50個線程去壓:


CPU只用到了80左右,TPS上不去,但是CPU一直還有20%
cpu還好,只用了80左右,util也不是很頻繁,才50%而已,可以接受,但是tps再怎么壓也壓不上去了,那么問題出現在哪呢,我們可以看下CPU消耗在哪里和線程的情況
cpu消耗具體每個占用情況,用jprofile 可以看

GC也很正常

看線程狀態:

發現有大量得等待線程。。
線程消耗: jstack pid (這個都是快照,可以多搞幾次 ,比如jstack pid >my.log,jstack pid >my1.log , jstack pid >my2.log)
關注線程狀態,這里需關注TIME WAITING
關注業務線程,很長 cn 的包或者是org的包主要是
系統線程一直time waiting很正常,業務一直time waiting 就不正常了


上圖的連接池為什么要等待呢?
並發數太多,連接池太少,很多連接池的連接再等待
發現最大得連接數才5個,原來是這個原因


數據庫查看可支持最大鏈接數:

show variables like '%connections%';
show variables like '%thread%';

netstat -anp |grep 3306 查看當前鏈接數

重新壓測后,發現,雖然也有time waiting ,但是信息很短,沒有和業務相關的

修改最大鏈接數為50個,重新壓測,壓測結果
在自己筆記本上線程50,80,100個壓測時,服務器CPU總是還有20%左右未使用,那么感覺壓力還不夠,通過在在自己筆記本jmter 150個線程,服務器100個線程開始繼續壓測,結果:



說明大概和我得想法相吻合,壓力不夠大!因為其他數據都正常
