為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 的磁盤空間。