1、着手在測試前:理清數據流向,數據流程分解
通過繪制數據流向圖,以便清晰的列出所有可能出現瓶頸的位置,避免在分析過程中遺漏可能的瓶頸點。
系統架構分解——水池模型
要查找瓶頸,首先要對系統的架構有詳細的了解,清楚知道所有可能成為瓶頸的位置。只有這樣才能在遇到問題是合理的設計
測試用例,對流程的各個步驟進行逐一排查。
舉個例子,家里廚房的水池下水堵了,我們要找原因,首先得知道水池的下水道都有哪些部分:
簡單的看,可以把下水道分解為水漏、上連接管、回水彎、下連接管最后接入地漏。再查找堵塞位置時,我們就可以將水直接導入回水彎,排除水漏和上連接管道堵塞的可能。
應用在測試中,我們也可以利用直接向應用中間件發請求,來排除Web代理層的瓶頸。
通過繪制流向圖,可以更清晰的展現系統中數據流向,幫助我們在定位瓶頸的過程始終能迅速的分析預計到下一個可能的瓶頸位置。
如上圖,就是在play一個Mobile game時的數據流向圖。
2、最直觀的指征:檢索日志中的異常
日志是系統異常的最直接反映,通過客戶端(負載工具端)、服務器端的日志,可以迅速確定瓶頸可能存在的方向。一些在大用戶量大並發情況下的功能問題,也會在錯誤日志中體現。
在
性能測試過程中,一般情況是不把全部日志打開的,而是盡量保持與生產環境的設置相同,生產環境開啟什么樣的日志級別,在性能測試環境中也應該開啟同樣的級別。
但是往往在生產環境出於性能考慮,並不會把日志級別開的非常高,所以在發現系統存在性能問題時,我們可以適當調高日志級別,以便獲得更多的信息。
在日志中,我們可以由一些關鍵字直接推斷出系統的問題所在,比如:
· Too many open files
Linux下存在句柄數限制,系統的默認值較小,在測試前應該優化,另外還要懷疑是否程序存在打開句柄卻在某些情況下沒有關閉。
· OutOfMemoryError/Cannot allocate memory
Java環境的虛擬內存異常,往往需要關注是否有溢出。
· SQLException
數據庫語句執行異常,一般日志中還會有數據庫返回的信息。
· Connection closed/connection refused
連接被關閉被拒絕,一般是連接數限制不能承擔當前的壓力。
3、最底層的反映:分析硬件資源占用
硬件資源也是系統性能達到瓶頸點的重要指征,如果沒有在日志中找到異常,那么通過監控硬件資源消耗,往往可以發現系統的資源瓶頸。
3.1 CPU占用率
CPU的高占用,並不一定表示有問題,因為實現最優性能的一方面就是充分發揮當前的硬件資源能力。
但是如上圖這樣CPU長期出於滿負荷,就很值得我們關注,至少說明在大多數情況下,系統已經是在耗用最大的計算能力進行計算,運算能力已經成為瓶頸。
另外還要注意CPU是消耗在User還是Sys還是Wait, 如果是Wait,還要觀察其他硬件資源,查看CPU是在等待什么。
3.2 內存占用
內存在性能測試中是被重點關注的指標,因為它是反映重大缺陷——內存泄露的最直接指標,但是我們應該注意到,在JAVA框架中的內存泄漏是發生在虛擬內存中的。
觀察內存/虛擬內存的占用情況,尤其是在壓力消失后的內存占用恢復情況,是比較直接的判斷內存泄漏的依據。
如果觀察到如上圖的內存使用情況,在每次Full GC后,占用的內存都沒能恢復到原來的水平,如果在壓力撤除一段時間后,內存依舊不能恢復,那么十有八九當前系統存在內存泄漏。
3.3 磁盤I/O
通常情況下,磁盤是計算機中速度最慢的一個子系統,因此很多情況中,磁盤I/O會成為系統的瓶頸。實際上在設計高性能系統的時候,會把避免磁盤I/O作為一個首要准則。
雖然當前的技術發展讓存儲系統的讀寫速度不斷提升,但高昂的成本使得大多數情況下,高速存儲會使用在數據庫或文件服務器上,而不會使用在應用服務器中。所以在我們進行性能測試時,要更多的注意應用服務器的磁盤使用情況。
3.4 網絡I/O
很多時候大家都容易忽略網絡對系統的影響,實際上網絡帶寬在一些情況下也會成為系統的瓶頸。一旦在業務的請求和響應中包含較大的數據傳輸時,往往會遇到網絡瓶頸。因為更多的時候服務器采用的還是以太網卡,1000M網卡在全雙工模式下傳輸速率也只有80M/s,如果響應中包含報表、圖片之類的大尺寸數據,很有可能在性能測試中出現網絡瓶頸。
還有一點就是不要忽略回環地址傳輸的影響,比如一些應用訪問本地監聽的其他服務,都會受到網卡的傳輸速率限制的影響。
4、軟件性能軟肋:數據庫的監控分析
對於Web系統,超過七成的瓶頸都出現在數據庫子系統,因此在進行之前幾步不能明確瓶頸位置的時候,應優先進行數據庫的監控分析。
Oracle數據庫監控工具
Oracle本身提供了ASH,AWR等Report來幫助進行性能分析,但是對於測試人員來說,掌握這些需要較深入的數據庫知識學習,不是一朝一夕可以達成的。而一些第三方提供的工具,通過圖形界面,可以更加直觀的幫助我們進行Oracle數據庫的監控和分析。
Lab128就是國內開發的一塊很不錯的共享軟件,而且它還提供無限期的試用key,可以免費試用。
Oracle中的等待事件
判斷Oracle中的瓶頸,了解Oracle中的等待事件Wait event,對於查找瓶頸有很大的幫助。在Oracle中,處理SQL的過程,會產生一系列的等待事件。
有等待事件並不代表數據庫存在瓶頸,正常的處理也會有等待事件,但如果發現等待事件激增,或者SQL執行緩慢,這時候等待事件中排名靠前的事件將會直接反映出瓶頸所在。
上圖是在測試中的某一時刻,log sync的等待事件突然增高,同時數據庫的吞吐率大幅下降,原本正常的SQL執行速度也突然變長。
因為壓力並沒有突然改變,很有可能是寫log的過程出現了問題,或者是在傳輸過程,或者是在存儲子系統。后來經過排查,發現是存儲集群的一個存儲單元出現故障導致寫入速度變慢致使出現大量等待。
5、最后的大殺器:應用服務器監控及代碼分析
如果沒能在其他位置發現瓶頸,那么軟件程序所運行的平台——應用服務器很可能是最大的潛在瓶頸點,進行應用服務器的監控與分析將是我們最后的大殺器。
5.1 常見的軟件資源種類
相對於硬件資源,軟件資源往往容易被忽略,它不像CPU占用率那么讓人更直觀的和性能聯系起來,但是實際上,軟件資源同樣限制着軟件系統能達到什么樣的性能。
軟件資源不論是在Web層,應用層還是在數據庫層,都可以按“入口”、“內部”、“出口”來划分。對於常見的原因中間件,“入口”就是如HTTP連接池之類,是數據來源方向的相關設置,比如連接數限制,超時時間,連接回收策略等等;“內部”就是處理請求的各項資源,不如線程數,線程調度策略,虛擬內存設置,GC策略等等;“出口”則是向后端交互的各項資源,如數據庫連接池的配置。
5.2 應用中間件監控
要了解軟件資源是否成為瓶頸,我們就需要監控這些軟件資源指標。以JAVA環境為例,Weblogic 本身就有控制台,提供了各種計數器。
上圖顯示的是Execute Threads的計數器,對請求的處理就在這些Thread中進行。
Tomcat也有開源的控制台,常用的像PSI-Probe,提供了Tomcat服務器各項資源的圖形化監控。如下圖中對JVM的監控。
5.3 應用中間件剖析
僅僅監控只能初步判斷問題的方向,例如發現ExecuteThreads持續的增加,我們雖然知道這個現象不正常,但是想要確定是程序中的哪個方法導致了當前問題,我還需要其他的工具進行深入剖析。
對於Java程序,最常用的工具有JProfiler,YourKit,他們的原理類似,都是要把一個小插件掛在到應用服務器上,以獲取需要的程序運行信息。
而Sun在JDK1.7后版本整合了繼承自JRockit的MissionControl,也提供了很強大的分析監控功能,而且開銷較小,確實是個不錯的選擇。
它提供的Mem leak detector可以對對象的創建進行趨勢分析,幫你找到最有可能出現泄漏的對象,
再通過展開剖析工具中的invoke tree,找出創建該對象的方法,可以更細致的定位問題的原因。
同時,Call tree 也可以依據CPU時間進行分析,找到在虛擬機中消耗最高的方法。
轉載:http://www.51testing.com/html/03/n-3649003-2.html









