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

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

在第一篇中,咱們初步介紹了 xhprof,以及如何安裝和運行分析器。在本文,咱們將介紹 Xhgui——用於審查並比較 xhprof 數據的用戶界面(UI)。html

使用 Xhgui

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

術語

爲了提升 Xhgui 的使用效率,你須要熟悉許多術語:正則表達式

  1. 調用次數:函數調用的次數sql

  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 工程師編譯整理)

相關文章
相關標籤/搜索