在講如何定位系統性能瓶勁之前,請讓我講一下系統性能的定義和測試,因為沒有這兩件事,后面的定位和優化無從談起。
一、系統性能定義
讓我們先來說說如何什么是系統性能。這個定義非常關鍵,如果我們不清楚什么是系統性能,那么我們將無法定位之。我見過很多朋友會覺得這很容易,但是仔細一問,其實他們并沒有一個比較系統的方法,所以,在這里我想告訴大家如何系統地來定位性能。 總體來說,系統性能就是兩個事:
一般來說,一個系統的性能受到這兩個條件的約束,缺一不可。比如,我的系統可以頂得住一百萬的并發,但是系統的延遲是2分鐘以上,那么,這個一百萬的負載毫無意義。系統延遲很短,但是吞吐量很低,同樣沒有意義。所以,一個好的系統的性能測試必然受到這兩個條件的同時作用。 有經驗的朋友一定知道,這兩個東西的一些關系:
二、系統性能測試
經過上述的說明,我們知道要測試系統的性能,需要我們收集系統的Throughput和Latency這兩個值。?
再多說一些,
性能測試有很多很復要的東西,比如:burst test等。 這里不能一一詳述,這里只說了一些和性能調優相關的東西??傊阅軠y試是一細活和累活。
三、定位性能瓶頸

有了上面的鋪墊,我們就可以測試到到系統的性能了,再調優之前,我們先來說說如何找到性能的瓶頸。我見過很多朋友會覺得這很容易,但是仔細一問,其實他們并沒有一個比較系統的方法。
3.1)查看操作系統負載
首先,當我們系統有問題的時候,我們不要急于去調查我們代碼,這個毫無意義。我們首要需要看的是操作系統的報告。看看操作系統的CPU利用率,看看內存使用率,看看操作系統的IO,還有網絡的IO,網絡鏈接數,等等。Windows下的perfmon是一個很不錯的工具,Linux下也有很多相關的命令和工具,比如:SystemTap,LatencyTOP,vmstat, sar, iostat, top, tcpdump等等 。通過觀察這些數據,我們就可以知道我們的軟件的性能基本上出在哪里。比如:
1)先看CPU利用率,如果CPU利用率不高,但是系統的Throughput和Latency上不去了,這說明我們的程序并沒有忙于計算,而是忙于別的一些事,比如IO。(另外,CPU的利用率還要看內核態的和用戶態的,內核態的一上去了,整個系統的性能就下來了。而對于多核CPU來說,CPU 0 是相當關鍵的,如果CPU 0的負載高,那么會影響其它核的性能,因為CPU各核間是需要有調度的,這靠CPU0完成)
2)然后,我們可以看一下IO大不大,IO和CPU一般是反著來的,CPU利用率高則IO不大,IO大則CPU就小。關于IO,我們要看三個事,一個是磁盤文件IO,一個是驅動程序的IO(如:網卡),一個是內存換頁率。這三個事都會影響系統性能。
3)然后,查看一下網絡帶寬使用情況,在Linux下,你可以使用iftop, iptraf, ntop, tcpdump這些命令來查看?;蚴怯肳ireshark來查看。
4)如果CPU不高,IO不高,內存使用不高,網絡帶寬使用不高。但是系統的性能上不去。這說明你的程序有問題,比如,你的程序被阻塞了??赡苁且驗榈饶莻€鎖,可能是因為等某個資源,或者是在切換上下文。
通過了解操作系統的性能,我們才知道性能的問題,比如:帶寬不夠,內存不夠,TCP緩沖區不夠,等等,很多時候,不需要調整程序的,只需要調整一下硬件或操作系統的配置就可以了。
3.2)使用Profiler測試
接下來,我們需要使用性能檢測工具,也就是使用某個Profiler來差看一下我們程序的運行性能。如:Java的JProfiler/TPTP/CodePro Profiler,GNU的gprof,IBM的PurifyPlus,Intel的VTune,AMD的CodeAnalyst,還有Linux下的OProfile/perf,后面兩個可以讓你對你的代碼優化到CPU的微指令級別,如果你關心CPU的L1/L2的緩存調優,那么你需要考慮一下使用VTune。 使用這些Profiler工具,可以讓你程序中各個模塊函數甚至指令的很多東西,如:運行的時間 ,調用的次數,CPU的利用率,等等。這些東西對我們來說非常有用。
我們重點觀察運行時間最多,調用次數最多的那些函數和指令。這里注意一下,對于調用次數多但是時間很短的函數,你可能只需要輕微優化一下,你的性能就上去了(比如:某函數一秒種被調用100萬次,你想想如果你讓這個函數提高0.01毫秒的時間 ,這會給你帶來多大的性能)
使用Profiler有個問題我們需要注意一下,因為Profiler會讓你的程序運行的性能變低,像PurifyPlus這樣的工具會在你的代碼中插入很多代碼,會導致你的程序運行效率變低,從而沒發測試出在高吞吐量下的系統的性能,對此,一般有兩個方法來定位系統瓶頸:
1)在你的代碼中自己做統計,使用微秒級的計時器和函數調用計算器,每隔10秒把統計log到文件中。
2)分段注釋你的代碼塊,讓一些函數空轉,做Hard Code的Mock,然后再測試一下系統的Throughput和Latency是否有質的變化,如果有,那么被注釋的函數就是性能瓶頸,再在這個函數體內注釋代碼,直到找到最耗性能的語句。
最后再說一點,對于性能測試,不同的Throughput會出現不同的測試結果,不同的測試數據也會有不同的測試結果。所以,用于性能測試的數據非常重要,性能測試中,我們需要觀測試不同Throughput的結果。
(編輯:小酷)
掃碼添加客服微信
掃碼關注公眾號
酷網(大連)科技有限公司
致力于為客戶品牌提供完善解決方案
統一服務電話:0411-62888851