如何定位效能瓶頸
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,jvisualvm,他們的原理類似,都是要把一個小外掛掛在到應用伺服器上,以獲取需要的程式執行資訊。
而Sun在JDK1.7後版本整合了繼承自JRockit的MissionControl,也提供了很強大的分析監控功能,而且開銷較小,確實是個不錯的選擇。
它們提供的記憶體洩漏檢測工具可以對物件的建立進行趨勢分析,幫你找到最有可能出現洩漏的物件,
再通過展開剖析工具中的invoke tree(呼叫樹),找出建立該物件的方法,可以更細緻的定位問題的原因。
同時,方法檢視也可以依據CPU時間進行分析,找到在虛擬機器中消耗最高的方法。