標籤:
乘風破浪,啟航未來!
做程式猿「媛」是一個苦逼的活,大周六地早起在技術群裡招呼,看到沒有啥人響應,說了一句,「估計都沒有醒」,然後一位哥們拋過來,「在加班」 !
做 Web 開發更是一個苦逼的活,不像是做 iOS,搞定用戶端,基本上就萬事大吉了。做 Web 開發不僅僅是要做後端,前端也需要瞭解和熟悉!
做前後端通吃的 DevOps 全棧工程師絕對是最苦逼的活,不但需要做開發,而且還要瞭解營運、最佳化,不會營運的工程師絕對不是一個好架構師!
但所幸的事,一個優秀的工程師儘管很忙,儘管要熟悉前後端、系統、運營、最佳化,但是在他的工具箱裡,放著一大堆工具,讓這種生活變得不那麼苦逼。
這裡就介紹四個讓我們 DevOps 生活變得美好的神器。分別是 Xdebug、XHProf 、OneAPM 和 SocketLog。
Xdebug
作為開發人員,睡得最踏實的事是對自己寫的代碼了如指掌,無論是從功能層面,還是效能層面。而做 Web PHP 開發,比較棘手的一件事情就是代碼的調試。作為指令碼語言,在遠程伺服器端運行,用戶端產生的全是 HTML 程式碼,一般認為我們無法準確地調試啟動並執行情況,更不要說單步調試、變數監控等事情了。其實這是有誤解的,有一個 PHP 擴充 Xdebug 能讓方便地讓我們調試遠程伺服器上啟動並執行代碼。
方法很簡單,從Xdebug下載最新版的原始碼。wget 解壓:
?
| 123456 |
tar –zxvf xdebug-2.3.3.tgz cd xdebug-2.3.3 phpize ./configure –with-php-config=/usr/bin/php-configmake make install |
再增加相應的配置到 php.ini ,需要注意有兩點: 1. xdebug 是 zend_extension 2. 連接埠預設是 9000,和 php-fpm 的預設連接埠衝突,所以這裡換用 9100
?
| 123456 |
[xdebug]zend_extension=/usr/lib/php/extensions/no-debug-non-zts-20121212/xdebug.so xdebug.remote_enable=on xdebug.remote_handler=dbgp xdebug.remote_host=localhost xdebug.remote_port=9100 |
這樣就裝好了,就是如此簡單,下面我們可以開始使用了。以 ThinkPHP 應用開發做例子吧。ThinkPHP 典型的單入口應用,調用層次相對複雜。所以想要瞭解呼叫堆疊還是比較麻煩的。要想得到某一行的呼叫堆疊,可以使用 PHP 內建的 debug_backtrace 函數可以獲得,但是不怎麼形象,返回來一個數組而已。而 Xdebug 就能讓這一切可視化起來。
配合 Xdebug 使用的是 Netbeans 內建的調試工具。首先通過喜好設定修改了一下 PHP 調試的連接埠,從9000改成9100,其他不用動。注意在第一行停止是選上的,這將在 PHP 程式調試時,運行到第一行 PHP 代碼時停止,在 ThinkPHP 中,即入口檔案 index.php 的第一行停止。
在本例中,筆者做了一個租車管理系統的樣本,項目名為 zuches。將代碼部署在 http://localhost/zuches 能訪問的地方,索引檔案是 index.php。
由於 index.php 是入口檔案,所以在 index.php 上點擊右鍵,選擇調試。
然後 Netbeans 自動開啟了如下地址,進入調試狀態 :http://localhost/zuches/index.php?XDEBUG_SESSION_START=netbeans-xdebug 同時運行位置指示停留到了 index.php 的第一行。如下:
點擊繼續運行,由於在 IndexController.class.php 的 index 方法中加上了斷點,所以位置指示又停留在了相應的斷點處。
這個時候,我們可以查看中斷時候的呼叫堆疊和變數了。通過堆棧可以方便地定位到各定位的類和相應方法。
各種變數,無論是局部變數和執行個體屬性,無論是 cookie,還是提交資料,都能在變數表中看到,一目瞭然。
總之,Xdebug 讓我們即使做的是伺服器端頁面和 API 開發,也可以像案頭應用開發一樣,調試每一行代碼了。
Xdebug 除了使用來進行單步調試之外,還能收集請求中的執行日誌,記錄每一個函數的執行過程。這些日誌可以用 wincachegrind 等工具進行分析,看到函數的調用棧和所花的時間。這裡不再贅述,我們也不是很推薦,因為 XHProf 在這塊要輕量級和強大的多,不用如此費勁地下載日誌,分析日誌。
XHProf
如前文所述,對於 PHP 中函數調用棧和效能分析,XHProf 將 Xdebug 開的先河繼承並發揚光大。XHProf 也是 PHP 擴充,不過不建議從http://pecl.php.net/package/xhprof 上下載,版本已有近2年沒有更新了,最好從https://github.com/phacility/xhprof 上下載。下載編譯配置和使用過程都很簡單。
配置只需要加上如下兩行:
?
| 12 |
[xhprof]extension=/usr/lib/php/extensions/no-debug-non-zts-20121212/xhprof.so |
然後將要相應的 XHProf 代碼配置到需要監控的頁面中,即可以獲得整個頁面的執行中,各函數的調用報表。XHProf 提供了樣本,配置成功運行如下:
如何看到上面圖中的效果呢?將 examples、xhprof_html、xhprof_lib 三個目錄放到瀏覽器能訪問到的地方,比如 localhost 的主目錄內。修改 examples/sample.php 中的換成 如:localhost/xhprof_html/。即可。
然後訪問 http://localhost/examples/sample.php 即可以得到輸出結果如下:
從 examples/sample.php 中可以看到,對於頁面的監測分析,在頁面頂部使用 xhprof_enable 開始,而效能的分析的結束,則是在頁面底部使用 xhprof_disable 結束 。這樣每次監控,都需要增加一段代碼,所以為了規範起見。對 XHProf 相關的操作進行了封裝。繼續採用上例 ThinkPHP 版租車系統的例子,看看如何整合 XHProf 分析。
首先將對 XHProf 的操作封裝成了一個類。
?
| 1234567891011 |
<!--?php class XHProf { private static $strNameSpace = ""; public static function init($strNameSpace = "myhome") { if (!function_exists("xhprof_enable")) { return; } self::$strNameSpace = strval($strNameSpace); $param = XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY; $path = getcwd(); require_once $path.‘/../xhprof_lib/utils/xhprof_lib.php‘; require_once $path.‘/../xhprof_lib/utils/xhprof_runs.php‘; xhprof_enable($param); register_shutdown_function("XHProf::genResult"); } public static function genResult() { $profiler_namespace = self::$strNameSpace; $xhprof_data = xhprof_disable(); $xhprof_runs = new XHProfRuns_Default(); $run_id = $xhprof_runs--->save_run($xhprof_data, $profiler_namespace); $profiler_url = sprintf(‘http://‘ . $_SERVER[‘HTTP_HOST‘] . ‘/xhprof_html/index.php?run=%s&source=%s‘, $run_id, $profiler_namespace); echo ‘ <p style="background: orange;"> ‘ . ‘<a href="‘ . $profiler_url . ‘" target="_blank">Profiler output</a> </p>‘; } } |
在這個封裝的類中,首先檢測了 xhprof_enable 函數是否存在,這可以用於判斷是否成功安裝配置了 xhprof 擴充。其次設定了參數,特別值得一提的是使用函數 register_shutdown_function 來註冊一個操作,這個操作在頁面結束之前,會自動運行。
這樣,在分析頁面效能之時,只需要在 ThinkPHP 應用的 index.php 上加上兩行,即可以了。
比如:
?
| 12 |
require_once "xhprof.php"; XHProf::init("zuches"); |
運行後,得到如下效果:
並且每一個頁面,都有這樣的輸出。點擊「Profiler output」即得到了報表。
在本例中,可以看到最後的整合方法,已耗用時間超過了2 S,是值得關注並最佳化了。從報表中,可以首先看到各個方法或者函數的調用次數,已耗用時間,以及可以層層點進去看到父子層級的調用關係 。
需要注意的是,線上上,如上使用 XHProf 要謹慎,即使開啟,也要有限制條件地開啟,比如目前使用者是某些調試開發人員使用者時才開啟。否則,普通使用者看到這樣的輸出,則不明所以,給使用者帶來困惑,當然,我們也可以不輸出,而將資料直接儲存,在後台系統中查看,這樣使用者就感受不到了。有一個工具,可以完全消除這些糾結。那就是 OneAPM,在第四部分我們再介紹。
未完,待續... ...
讓程式員不再苦逼的神器(上)