為PHP應用提速、提速、再提速!第2部分: 分析PHP應用程式以尋找、診斷和加速運行緩慢的代碼
“為PHP應用提速、提速、再提速!” 系列文章的第1部分示範了如何使用XCache(PHP作業碼緩衝) 加速整個網站。XCache(僅是少數幾種緩衝包中的一種)保留了編譯過程的輸出,去掉了其他冗餘的工作。只要頁面沒有發生變化,緩衝後的頁面就能夠勝任代理的作用。當頁面發生變化時,緩衝後的頁面就會變為無效並被替換掉。
作業碼緩衝 —— 以及一個作業碼最佳化器,通常由相同的包提供 —— 是一種加快網站響應的低成本技術。很多緩衝包是免費的,並且是開源的,無需改變任何代碼即可從中受益。
當然,在某些應用程式中,相比較實際的執行時間,將 PHP 原始碼檔案翻譯為其相應的作業碼所需的時間微不足道。串連到遠端資料庫伺服器,使用低效的 SQL 陳述式進行查詢,以及其他大量解析和操作資料的工作都非常的繁瑣,也因此增加了開銷,甚至產生浪費。良好的網路設計和靈巧的資料庫結構可以使時間冗長和查詢緩慢的情況有所改善,如果需要的話還可以向友好的專家請求協助。但是,如果代碼運行緩慢,您可能更希望自己處理。
但是從何開始呢?正如人們普遍認為的,在程式碼完成前調試代碼的做法很不明智 —— 因為代碼的首次實現可能會非常的迅速。當代碼正確且能實現相應的功能時,不管其表面上看起來運行緩慢還是實際如此,首先要做的就是對其效能進行測試或基準測試。不執行這樣的診斷而嘗試去最佳化代碼無疑是在黑暗中摸索。
一個簡單的效能指標是掛鐘時間(wall clock time),或測量頁面請求與完成呈現之間的實際延遲。對於某些情況 —— 比如在您自己的工作站本地啟動並執行 Web 服務器、資料庫和瀏覽器 —— 掛鐘時間能夠提供資訊。然而,掛鐘時間對於其他大多數情況而言並無實際意義,比如網路延遲時間、活動的 Web 服務器或者活動的資料庫。
一種更精確的測量 —— 甚至可以測量運行單個原始碼語句的時間 —— 可以採用程式碼分析器。分析器通常被實現為 PHP 運行時引擎的擴充,記錄語句開始和結束的 delta、記錄程式開始和結束之間的 delta 並捕獲對來到的請求形成響應的總時間。有了這種垂直度,就可以將語句、迴圈、函數、類或者是運行緩慢的庫作為分析目標。如果不是時間而是記憶體使用量出現了問題,那麼一個優秀的分析器還可以顯示組件的記憶體佔用情況。
PHP 的一個較流行的分析器是 Xdebug,它還為互動地調試 PHP 應用程式提供了伺服器掛鈎(hook)。(參見“調試的更好方法”以瞭解更多資訊。該系列的另一部分將探討進階互動式調試。) Xdebug 很容易從原始碼構建,將其作為 Zend 擴充進行安裝也非常簡單。(現在已有針對某些平台的二進位檔案。)當就緒後,對基於 PHP 頁面的每個請求都將產生可在 KCacheGrind 中查看的資料集。
構建並安裝 Xdebug
如果具備了 PHP 工具 + 生產力 phpize 和 php-config,而且具有對系統的 php.ini 設定檔的訪問權,那麼安裝和設定 Xdebug 只需幾分鐘的時間。下面給出的指導說明針對 Linux®,不過在 Mac OS X 上的安裝步驟實際上與此類似。(您可以從 Xdebug Web 網站找到針對 Microsoft® Windows® 的 Xdebug 先行編譯版本。)
Xdebug 的最新版本為 V2.0.0RC3(最終版本 V2.0.0 在您閱讀此文時也許已經可用)。下載並解包 tarball,然後切換到原始碼的子目錄。確保 phpize 和 php-config 位於 shell 的 PATH,準備使用 phpize 進行構建。
清單 1. 設定 Xdebug
$ wget http://www.xdebug.org/files/xdebug-2.0.0RC3.tgz
$ tar xzf xdebug-2.0.0RC3.tgz
$ cd xdebug-2.0.0RC3/xdebug-2.0.0RC3
$ phpize
Configuring for:
PHP Api Version: 20020918
Zend Module Api No: 20020429
Zend Extension Api No: 20050606
phpize 的產品是一個指令碼 —— 名為配置 —— 它對餘下的構建過程進行配置。要構建 Xdebug,在 make 後緊接著輸入 ./configure 即可。
清單 2. 構建 Xdebug
$ ./configure
checking build system type... i686-apple-darwin8.8.1
checking host system type... i686-apple-darwin8.8.1
checking for egrep... grep -E
...
$ make
...
Build complete.
(It is safe to ignore warnings about tempnam and tmpnam).
make 命令產生 Xdebug 擴充,xdebug.so。剩下的工作就是使用 sudo make install 進行安裝。
$ sudo make install
Installing shared extensions: /usr/lib/php/extensions/no-debug-non-zts-20020429/
註: 如果在終端視窗中運行最後一個命令,請選擇並複製最後一步中發出的目錄。在下一個步驟中將會用到它。
最後,要使配置資料視覺效果,必須使用 KCacheGrind 和 GraphViz。包含 K Desktop Environment (KDE)的 Linux 發行版很可能已經含有了 KCacheGrind 和 GraphViz。如果沒有包含,適合您所使用的 Linux 的那些版本也不難找到。Debian 使用者可以使用 Advanced Packaging Tool (APT) 快速安裝 KCacheGrind 和 GraphViz 以及所有包的依賴關係。
清單 3. 安裝 KCacheGrind
$ apt-cache search kcachegrind
valgrind-callgrind - call-graph skin for valgrind
kcachegrind - visualisation tool for valgrind profiling output
kcachegrind-converters - format converters for KCachegrind profiling visualisation tool
$ apt-cache search graphviz
graphviz - rich set of graph drawing tools
graphviz-dev - graphviz Libs and Headers against which to build applications
graphviz-doc - additional documentation for graphviz
libdeps-renderer-dot-perl - DEPS renderer plugin using GraphViz/dot
...
$ sudo apt-get install kcachegrind graphviz
...
如果沒有將 KDE 安裝到系統中,KCacheGrind、GraphViz 以及所有必要的內容將佔用大約 90 MB 的磁碟空間。