首頁 >後端開發 >php教程 >使用XHGui來測試PHP效能的教學課程

使用XHGui來測試PHP效能的教學課程

WBOY
WBOY原創
2016-07-25 08:45:01740瀏覽

Profiling是一種用來觀察程式效能的技術,非常適合發現程式的瓶頸或緊張的資源。 Profiling能夠深入程式的內部,展現request處理過程中每一部分程式碼的效能;同時,也可以確定有問題的請求(request);對於有問題的請求,我們也可以確定效能問題發生在請求內部的位置。對於PHP,我們有多種Profiling工具,本文主要集中在-XHGui,一個非常優秀的工具。 XHGui建構在XHProf之上(XHProf由Facebook發布),但是對於剖析結果增加了更好的存儲,同時增加了更加良好的信息獲取接口。從這方面來說,XHGui更像是一個全新的工具。

XHGui已經經歷過幾個版本的迭代,但當前版本提供了更漂亮的使用者介面,並且使用MongoDB儲存其剖析結果。相較於前一版本來說,所有這些方面都是巨大的改進;因為,前一版本更像是開發者設計的,採用文件來保存數據,使得收集的數據非常難以使用。 XHGui 2013是一個非常全面的Profiling工具,無論是對管理人員來說還是對於開發者;同時,XHGui 2013被設計的足夠輕巧以便能夠在生產環境下運作。

本文將一步一步示範程式的安裝,同時向你展現使用該工具可以收集的各方面資訊。

第一步:安裝依賴

因為XHGui有一些依賴項,所以我們第一步就是解決這個問題。底下的所有的教程都是基於Ubuntu 13.04平台的,當然,你應該可以把它們改編下來並適用到你自己的平台上。目前而言,我們需要安裝MongoDB, PHP,並且有一些安裝PECL拓展的能力。

首先,我們要安裝MongoDB,這邊有一些官方的安裝教程,你可以找到和你係統相關的細節,但是現在我將通過簡單的通過APT來安裝:

  1. aptitude install mongodb
複製程式碼

透過這個方式取得的MongoDB的版本可能不是最新的,因為這個產品的更新速度真的很快。但是,如果你想讓它保持一個很新的版本,你可以把MongoDB提供的函式庫加入你的套件管理器裡,這樣你就能得到一個最新的了。


同時,我們也需要針對PHP的Mongo 驅動。在倉庫中該驅動的版本有點老,為了今天的演示,我們將從Pecl中進行獲取。如果你的機器上沒有pecl指令,你可以透過下面的指令來安裝:

  1. aptitude install php-pear
複製程式碼

然後,我們透過下面的指令為PHP加入MongoDB的驅動程式:

  1. pecl install mongo
複製程式碼

為了完成安裝,最後我們需要在php.ini檔案中新增一行。但是,新版本的Ubuntu為配置PHP擴充功能提供了一個新系統,該系統更像Apache模組安裝——將所有的配置保存在一個地方,然後創建一個符號連結以啟動配置。首先,我們建立一個檔案來保存設置,儘管在本範例中僅需要在設置中新增一行以啟動擴充。我們將其保存在檔案/etc/php5/mods-available/mongo.ini,新增下面一行:

  1. php5enmod mongo
複製程式碼


複製程式碼
再次使用pecl來安裝xhprof擴充功能。程式目前僅是beta版本,因此安裝指令如下:
pecl install xhprof-beta


複製程式碼

命令列會再一次提示我們在php.ini新增一行。我們採用與上面相同的方法,建立檔案/etc/php5/mods-available/xhprof.ini,並在裡面新增如下如:
extension=xhprof.so
複製代碼此時,我們可以檢查這些模組是否已正確安裝—透過在命令列執行php -m命令。記住,不要忘記重啟Apache,以便web介面能夠啟用這些擴充功能。

安裝XHGui

XHGui本身主要由web頁面組成,它為XHProf擴充收集的資料提供更友善的介面。你可以從程式碼庫GitHub repo克隆;也可以直接下載zip文件,然後進行解壓縮。取得程式之後,確定快取目錄有足夠的權限以便web伺服器有權限寫入檔案。最後,執行安裝腳本:

  1. php install.php
複製程式碼

這就是程式安裝所需的一切,並且會自動安裝一些依賴程式;如果發生異常,安裝程式也會給你提示。

我比較喜歡將XHGui安裝在虛擬主機當中;這需要.htaccess檔案允許,也需要啟動RUL重寫。啟動URL重寫表示需要啟動mod_rewrite模組,透過下面的指令:

  1. a2enmod rewrite
複製程式碼

(不要忘記重啟Apache)。如果一切順利,你可以正常存取XHGui的URL並且可以看到如下內容:

201573145850225.png (300×210)

在虛擬主機中啟動XHGui

此時,我們希望啟動XHGui以便檢驗我們網站的效能。注意,效能測試最好在進行任何最佳化之前執行一次,以便檢測最佳化的效果。最簡單的方法是在虛擬主機中增加auto_prepend_file聲明,如下圖所示:

  1. ServerName example.local
  2. DocumentRoot /var/www/example/Thts/
  3. Options FollowSymLinks Indexes
  4. AllowOverride All
複製程式碼

一切就緒之後,你可以開始剖析網站的請求。 XHGui只會剖析網站請求的1%,所以為了讓XHGui取得有意義的數據,你需要讓XHGui運行一段時間或使用類似Apache Bench的測試工具批次提交一批請求。為什麼在100個請求當中XHGui只會剖析一個?因為XHGui的設計初衷就是足夠的輕巧以便在生產環境中使用,它不想對每個請求產生額外的開銷,1%的採樣率已經能夠為網站的總體流量提供較為清晰的概覽。

滿足資料

我使用測試虛擬機器執行本文所有的範例,並採用Joind.in API作為測試程式碼。為了產生一些流量,我將API測試案例運行了幾遍。你也可以在一定負載的情況下收集數據,所以你可以在壓力測試時使用XHGui,你甚至可以在上線站點中使用XHGui收集數據(聽起來很瘋狂,但是Facebook正式為了此應用才開發了該工具)。在向應用程式發送了一定的請求之後,重新訪問XHGui,現在它就已經保存了一些資料:

201573145913073.png (300×210)

該圖向我們展示了XHGui為我們分析的每一個請求,最新的請求排在第一位,並且為每一個請求展示了一些額外資訊。這些資訊包括:

  • URL:請求所存取的URL
  • Time:請求發起時間
  • wtor: "Wall Time" –請求所經歷的所有時間. 這是 "wall clock" time的簡稱,表示使用者等待請求完成所有的時間
  • cpu:花費在該請求上的CPU時間
  • mu:該請求所消耗的記憶體
  • pmu:請求處理過程中所消耗的最大記憶體

為了獲取每一遍請求("run")更為詳細的信息,你可以點擊每一個請求你感興趣的列。你可以點擊URL以便取得該URL所有請求的詳細資訊。無論哪種方法,你都可以獲得該請求更詳細的資訊:

201573145938626.png (300×210)

201573145957832.png (300×210)

這是一個非常長且非常詳細的頁面,所以我引用了兩個截圖(如果展示所有的資訊將需要5個截圖)。上面一幅圖的左邊部分展示了該請求相關的一些信息,以便幫助你跟踪這些統計信息與哪些方面有關;右邊的主要部分展示了最消耗時間的各部分以及在請求過程中每個函數調用所消耗的記憶體。在圖的下方有一個主鍵以表示每一欄。

第二幅圖展示了該請求每一個組成部分更為詳細的資訊。我們可以看到每一部分呼叫的次數以及時間消耗,還包括CPU和記憶體資訊。無論是inclusive或exclusive資訊都做了詳細的展示:exclusive表示僅是此方法呼叫所產生的消耗;inclusive不僅包含本函數所產生的消耗,還包括本函數呼叫的其他函數所產生的消耗。


XHGui另一個特性是「呼叫圖」(Callgraph),「呼叫圖」以生動的虛擬方式展示了時間是如何消耗的:

201573150016938.png (300×210)

這很好的展示了函數呼叫的層次。最好的一點是,該圖是可互動的,你可以拖曳以更好的查看連接;你也可以用滑鼠滑過「圓環」(blob)以查看更多的資訊。當你與它互動時,他會很好玩的彈回和移動,這不是一個非常重要的功能但卻讓我感覺非常好玩。

理解數據

擁有大量的統計數據非常重要,但是你很難知道從哪裡下手。對於一個效能不如預期的頁面採用以下步驟:首先,對每個函數的exclusive CPU時間進行排序,查看最消耗時間的函數清單。分析這些耗時的函數呼叫並進行重構和最佳化。

一旦做出了修改,讓剖析工具再次檢驗新版本的程序,測試性能的改進。 XHGui內建了完美的工具以比較兩次運行;點擊詳細資訊頁面右上角的「Compare this run"按鈕即可。這個按鈕會向你展示該URL每一次測試的結果,從中選擇一個你要比較的物件。對你想比較的對象,點選」compare「按鈕,XHGui將會轉向比較視圖,如下圖所示:

201573150035219.png (300×210)

統計表格展示了新版和舊版統計資訊的主要區別,包括每個資訊變更的實際數字以及百分比。上圖顯示,新版的請求等待時間僅為舊版的8%。統計表格詳細展示了每一個統計資料的改變,這些統計資料我們在」詳細資料「頁面能夠經常看到;你可以對任何一列進行排序以便查找你感興趣的資訊。

一旦你在某一方面成功的進行了重構,請查看詳細資訊頁面(detail page)以檢查新版本的實際效果,然後挑選其他方面進行最佳化。嘗試將記憶體使用或exclusive wall time 進行排序,以便挑選能夠最大限度地提高應用整體效能的函數進行最佳化。同時,不要忘記檢查呼叫的次數,一個重複呼叫的函數經過最佳化之後能夠成倍的提高程式的效能。

最佳化方法

你很難在量化成果之前知道自己改善了多少,這就是為什麼我們經常在對一個應用進行優化之前檢測它--不然你怎麼知道自己是否真的優化了它?我們也需要想想一組真實的數據應該怎麼表示,不然,我們可能會朝著一個不可能到達的目標前進。一個很有用的方法是:盡力去尋找需要使用的最適合的資料結構以及最小儲存空間。如果在你擅長的工作環境中,不能在半秒內執行一個「Hello world」程序,那麼就別指望用同樣的工具建立的網頁能有多好的表現。

上面的敘述並不是對程式框架(framework)的不敬;程式框架之所以存在是因為其方便使用、支援快速開發、容易維護。相較於親自手工編寫程式碼,程式框架在效能上的降低是我們綜合各方面進行折衷的結果。採用程式框架進行應用程式開發是能夠盡快上線的一個很好的方法,當需要的時候,你可以使用Profiling工具分析並改進程式的效能。例如,Zend Framework 1的許多模組能夠提供非好強大的特性,但是並能非常低下;採用Profiling工具就能確定性能低下的部分並將它們進行替換。其他所有的框架都有類似的問題,XHGui能夠向您展示問題的所在並檢查他們是否對您的程式產生了可量化的影響。


在你的程序之外,一些其他的策略對佔領上風或許遲早有用:

  • 小心非危險的慢速關聯函數(not-dangerously-slow-but-related functions)在一個頁面上露面。如果你的頁面在格式化要點處理的 view helper 中的一系列函數中花去了它時間的 50%(我承諾這是個假想的例子),那麼你可能想要去研究重構整個元件。
  • 少做。嘗試移除特性,如果性能比它們重要。
  • 當心一個請求中產生但沒有在特殊的視圖中用到的內容,或未改變卻被多次重新生成的內容。
  • 好的快取策略。這將是關於它的​​另一篇文章,但考慮用PHP 中的一個OpCode 快取(從PHP 5.5 起內建),在你的web 伺服器前方添加一個反向代理,簡單地為那些不怎麼經常改變的內容發送適當的快取頭。
  • 暴力去耦合。如果有一個可怕的資源緊張的特殊功能,把它從你的 web 伺服器上去掉。或許它可以被非同步處理,所以你的程式可以只是添加一個訊息到佇列,或移動到另一個單獨的伺服器並作為一個單獨的服務模型來存取。無論哪種方式,分離將幫助減少你的 web 伺服器的負載,同時啟用了有效的擴充。

XHGui是你的朋友

XHGui安裝簡單、使用時如影隨形、很棒的輸出以至於可以拿到董事會議上進行展示。它能辨識出我們應用中的錯誤,幫助我們確認應用程式真的起作用(或沒有!)。這可能會經歷一些重複的過程,不過,不管你之前有沒有用過XHProf、XHGui,我勸你花點時間在你的應用上試試,你會對你的發現大吃一驚。

XHGui, PHP


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn