PHP 效能分析第二篇: Xhgui In-Depth

OneAPM官方技術部落格發表於2015-09-22

【前言】這是國外知名博主 Davey Shafik 撰寫的 PHP 應用效能分析系列的第二篇,第一篇介紹 Xhprof/Xhgui,第三篇則關注於效能調優實踐。

在第一篇中,我們初步介紹了 xhprof,以及如何安裝和執行分析器。在本文,我們將介紹 Xhgui——用於審查並比較 xhprof 資料的使用者介面(UI)。

使用 Xhgui

Xhgui 提供了許多協助效能評估的功能,既適用於單次執行,也能滿足聚合環境——讓你精確至具體問題、發現趨勢。

術語

為了提高 Xhgui 的使用效率,你需要熟悉許多術語:

1.呼叫次數

函式呼叫的次數

2.[包含] 實際執行時間 (wt)

函式實際執行時間

3.[包含] CPU 使用/CPU 用時 (cpu)

執行該函式 CPU 所用時間

4.[包含] 記憶體使用 (mu)

目前該函式使用的記憶體量

5.[包含] 記憶體使用量峰值 (pmu)

函式使用的記憶體高峰

6.專一實際執行時間 (ewt)

7.專一 CPU 時間 (ecpu)

8.專一記憶體使用量 (emu)

9.專一記憶體使用量峰值 (epmu)

術語2至5都是包含型的測量指標(儘管不總是明確指出),這些指標會計算函式及其子函式的呼叫。術語6至9是專一型的測量指標——它們只計算函式本身的資源呼叫。所有的測量數值都是呼叫該函式後的累計值。(例如,如果一個函式呼叫兩次,第一次用時900毫秒,第二次,因為快取的緣故,只耗時40毫秒,最終顯示的時間就是940毫秒)。

準備開始

一旦在 HTTP 伺服器上執行 Xhgui ,你首先會看到:

在頂部,你會看到一個選單,它包含:

Recent — 近期大部分執行 (分頁)

Longest wall time — 根據實際執行時間從最慢的執行開始排序

Most CPU — 從佔用 CPU 時間最多的執行開始排序

Most Memory — 從佔用記憶體最多的執行開始排序

Custom View — 執行 mongo DB 自定義查詢

Watch Functions — 應該出現在審查頁面頂部的標記函式

Waterfall — 從實驗性檢視檢視併發請求的相互影響

在本教程中,我選擇分析用 Wordpress 搭建的網站效能。網際網路上多於18%的網站都是基於 Wordpress 搭建的,這意味著,即便是對 Wordpress 很小的效能改進, 亦能產生巨大影響。

檢視一次執行的效能資料

分析了幾個頁面的效能(或匯入了檔案)之後,你會看到它們羅列在 Xhgui :

檢視一次執行的效能資料,只需點選日期。

通過單擊適當的表頭,你可以根據實際執行時間 (wt) , CPU 時間 (CPU) 、記憶體使用量 (mu) 或 記憶體使用量峰值 (pmu) 檢視這些執行情況。從而輕易找出最慢的頁面。

單個效能頁面展示了相當多的資訊。在左側可以看到執行的總體情況,以及執行時的環境資料,包括 GET (或 POST) 資料和伺服器資料:

在右側,展示了 watch function 列表:

該表詳細列出了函式名稱,呼叫次數 ,專一實際執行時間 (ewt), 專一記憶體使用量(emu)、和專一記憶體使用峰值(epmu)。此外,你可能會注意到頁面頂部的兩個按鈕,“View Callgraph(檢視呼叫圖)” 和 “Compare this run(對比此次執行)”。

接下來,我們看到兩個圖。圖一展示了專一實際執行時間最長的六個函式,該時間是用在函式本身的時間(不包含任何子函式呼叫所佔的時間)。圖二展示記憶體使用量最大的六個函式。這些圖通常能將你指向效能瓶頸。

函式的細節在下方列出。如果將滑鼠滑過圖中的圓柱,這些資訊也將出現在提示框中。

最後,我們看到效能分析器收集到的大宗資訊——函式列表:

該表包含一個浮動的標題欄(即便滑鼠向下滾動,該欄目也會保持在螢幕頂端),包含函式名,呼叫次數,和前面提到的專一和包含的測量值。

預設情況下,該表按專一實際執行時間排序,時間最長者排在首位。通常你不會想改變這一次序,因為這讓你快速找出執行最慢的函式,除非你想看記憶體使用量。

當你想檢視一個函式的執行情況時,點選該函式,會跳轉到其詳細頁面。該頁面首先會遞迴展示函式本身的細節。接下來, “Parent Functions(父函式)” 部分列出所有直接呼叫該函式的函式。最後,“Child Functions(子函式)”列出該函式直接呼叫的其他函式。

父函式按照專一實際執行時間,列出標準列表資料。

你需要確定:是函式本身執行緩慢,還是呼叫它的次數太多導致累積的實際執行時間太長。通過檢查該函式的呼叫計數,然後回顧其父函式列表。

如果你覺得函式呼叫次數沒問題,你就要看看子函式執行情況。此處才是函式執行消耗時間的部分。

子函式只顯示包含測量值;這是因為你想很快找到耗時最長的程式碼路徑。

你可以點選每個子函式,下鑽到相同的細節檢視,並進行相同的分析。

比較效能資料

Xhgui 最好的特性在於比較兩個不同的執行。這使你:

  • 修改系統 (如啟用 opcache , mysql 查詢快取) 並比較結果
  • 修改程式碼(程式碼或 SQL 優化)並比較結果
  • 將異常的執行與“正常”執行比較

比較兩個執行時,你必須首先選擇一個基礎執行。點選其日期就能看到該執行的詳細資訊頁。

接下來,單擊右上角的“Compare this run” 按鈕:

接著會跳轉到同一 URL 下的執行列表,你可以選擇一個進行比較:

點選你想進行比較的執行的 "Compare" 按鈕,將跳轉到比較頁面。

比較檢視只顯示兩個執行之間的差異。在頁面頂部顯示比較中的兩個執行,以及一些輔助修改排序的按鈕。

接下來是概覽:

儘管這個表的所有資訊都有用,但特別值得注意的兩個差別是 "函式呼叫次數" 和 "專一實際執行時間" 。

函式呼叫次數的差別暗示著兩次執行的重要差異:不同的程式碼路徑或快取。第一個差別可能是有意的優化導致的,但若這並非你的目的,比較這兩個執行很可能不會有太大的價值。另一方面,快取是有益且有效的提高效能的方式。這種比較很容易驗證快取是否發生。

包含實際執行時間的百分比差展示了效能調優的實際成果。理想情況下,我們將看到一個較小的百分比——這是第二執行時間比上第一次執行時間的佔比。在截圖中,第二次執行只花了第一次執行79%的時間,這意味著效能提升了21%。

最後,我們看到功能細節:

請記住,該檢視只展示差別。差別通過綠色的負數和紅色的正數表示。(負數表明呼叫次數更少,實際執行時間更短,CPU 耗時更短或記憶體消耗更少)如果沒有差異,則顯示為灰色的0。

與其他表一樣,您可以在任意列進行排序,預設的順序方式是函式的呼叫次序。

在這裡你可以驗證,你做的改變是否確有效果,是否為預期效果。你也可以在效能下降時使用該檢視追蹤原因。

效能提高的一個好例子是:基於一個條件只呼叫一個函式——例如,您可能不需要過濾資料,如果之前已經做了。

當你做出這種改變時,你會預期過濾函式的呼叫次數減少,從而效能提升。

這兩件事都可以在此處得到驗證,以及其他意想不到的原因——你的條件比過濾本身需要更長的時間?如果真是如此,這將對效能產生負面影響。

在此處,我們可以看到, NOOP_Translations::translate 和 apply_filter 的呼叫次數都減少了,但是 apply_filter 的專一記憶體使用量增加了133560個位元組!

發現趨勢

對我來說,Xhgui 最強大的功能是檢視趨勢。因為 xhprof 是被動分析器,可以在所有環境中啟用 (dev、qa、階段性、生產),可以持續地對流量取樣分析。

審查給定 URL 的所有資料,只需在執行列表點選它:

這將跳轉到該 URL 執行頁面。

該頁面顯示兩個重要圖表。第一個顯示實際執行時間和 CPU 時間,第二個顯示記憶體使用情況和峰值記憶體使用。這些圖表列表中執行的資料,包括每次執行的 URL,時間,實際執行時間、CPU時間、記憶體使用和峰值。

這些圖是檢視趨勢和異常值的關鍵所在。但是該如何處理這些資訊呢?

對於資料異常者,首先你可以將滑鼠懸浮在它上面驗明正身,接著,你可以看一下它的單次執行。或用其他正常執行與其比較,從而發現不同。

對於趨勢,最好的選擇是審查趨勢開始的時間——你在此時新增快取了嗎?隨著快取變得更加完整,整體趨勢應該向下。或者你的快取失效,你將看到一個上升趨勢,此時快取正在重建。

預設情況下,這些圖表顯示最近100次執行,你可以點選下一頁去檢視更久遠時間的執行。

另外,你可以點選搜尋按鈕來定製顯示的介面:

單擊該按鈕將顯示搜尋表單:

你可以搜尋具體日期之間的執行。也可以檢視最近30分鐘、1小時、2小時、12小時、24小時、1周、2周或30天內的執行——更小的時間間隔適合評估效能調優的結果。

最後,你可以使用 PHPs DateTimeIntervalInterval 規範格式指定自定義時間區間——例如,最近2天可使用 P2D,最近15分鐘可使用 PT15M。

Watch Functions

Watch functions 允許你通過正規表示式識別特定的函式,或函式組,並顯示在單個執行頁面(見前文)。

因為可以使用正規表示式,我們可以輕易地檢視一個模組或擴充套件中的功能。

For example, to watch all MySQL activity, simply add one of the following: 例如,檢視所有 MySQL 活動,只需新增如下列表的任意一項:

  • mysql_(.*)for ext/mysql
  • mysqli(.*)for ext/mysqli
  • pdo(.*)for PDO (適用於所有PDO-based資料庫互動)

如果你使用諸如 Propel 的 ORM,你可能使用 (.)Query::(.) 追蹤所有 Query 類。

呼叫圖(Callgraphs)

Xhprof 的最後一部分是呼叫圖 ,該圖展示執行的程式碼執行路徑。

點選單一執行頁面頂部的“View Callgraph”按鈕即可檢視呼叫圖。

在呼叫圖中,拖拽結點可以更好地檢視資料。滑鼠懸浮在每個點選上,會顯示其包含實際執行時間,同時允許你進入該函式的詳情頁。

更直觀地檢視圖,請點選: 體驗免費使用OneAPM線上PHP應用效能分析SaaS服務!

下一章節

在第三部分也即最後一部分,我們會使用 xhprof 資料來優化程式碼。我們也會簡單地介紹其他優化程式碼的工具。 (本文系應用效能管理領軍企業 OneAPM 工程師編譯整理)

相關文章