作程序猿「媛」是一個苦逼的活,大週六地早起在技術羣裏招呼。看到沒有啥人響應,說了一句。「預計都沒有醒」。而後一位哥們拋過來,「在加班」 !php
作 Web 開發更是一個苦逼的活。不像是作 iOS,搞定client。基本上就萬事大吉了。css
作 Web 開發不只僅是要作後端。前端也需要了解和熟悉!html
作先後端通吃的 DevOps 全棧project師絕對是最苦逼的活,不但需要作開發,並且還要了解運維、優化。不會運維的project師絕對不是一個好架構師。前端
但所幸的事。一個優秀的project師雖然很是忙,雖然要熟悉先後端、系統、運營、優化,但是在他的工具箱裏,放着一大堆工具。讓這種生活變得不那麼苦逼。java
這裏就介紹四個讓咱們 DevOps 生活變得美好的神器。各自是 Xdebug、XHProf 、OneAPM 和 SocketLog。node
做爲開發人員,睡得最踏實的事是對本身寫的代碼瞭如指掌,不論是從功能層面,仍是性能層面。而作 Web PHP 開發,比較棘手的一件事情就是代碼的調試。做爲腳本語言,在遠程server端執行,client生成的全是 HTML 代碼,通常以爲咱們沒法準確地調試執行的狀況。更不要說單步調試、變量監控等事情了。事實上這是有誤解的。有一個 PHP 擴展 Xdebug 能讓方便地讓咱們調試遠程server上執行的代碼。python
方法很是easy,從 Xdebug 下載最新版的源碼。
wget 解壓:linux
tar –zxvf xdebug-2.3.3.tgz
cd xdebug-2.3.3
phpize
./configure –with-php-config=/usr/bin/php-config
make
make install
再添加對應的配置到 php.ini
,需要注意有兩點:android
1. xdebug 是 zend_extensionios
2. port默認是 9000。和 php-fpm 的缺省port衝突,因此這裏換用 9100
[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 調試的port,從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 讓咱們即便作的是server端頁面和 API 開發。也可以像桌面應用開發同樣。調試每一行代碼了。
Xdebug 除了使用來進行單步調試以外,還能收集請求中的執行日誌。記錄每一個函數的執行過程。這些日誌可以用 wincachegrind
等工具進行分析。看到函數的調用棧和所花的時間。這裏再也不贅述,咱們也不是很是推薦,由於 XHProf
在這塊要輕量級和強大的多,不用如此費勁地下載日誌,分析日誌。
如前文所述,對於 PHP 中函數調用棧和性能分析,XHProf 將 Xdebug 開的先河繼承併發揚光大。XHProf 也是 PHP 擴展,只是不建議從 http://pecl.php.net/package/xhprof 上下載,版本號已有近2年沒有更新了,最好從 https://github.com/phacility/xhprof 上下載。下載編譯配置和使用過程都很是easy。
配置僅僅需要加上例如如下兩行:
[xhprof]
extension=/usr/lib/php/extensions/no-debug-non-zts-20121212/xhprof.so
而後將要對應的 XHProf 代碼配置到需要監控的頁面中,即可以得到整個頁面的執行中。各函數的調用報表。XHProf 提供了演示樣例,配置成功執行例如如下:
怎樣看到上面圖中的效果呢?將 examples
、xhprof_html
、xhprof_lib
三個文件夾放到瀏覽器能訪問到的地方,比方 localhost
的主文件夾內。
改動 examples/sample.php
中的 <xhprof-ui-address>
換成 如:localhost/xhprof_html/
。就能夠。
而後訪問 http://localhost/examples/sample.php
即可以獲得輸出結果例如如下:
從 examples/sample.php
中可以看到,對於頁面的監測分析。在頁面頂部使用 xhprof_enable
開始,而性能的分析的結束,則是在頁面底部使用 xhprof_disable
結束 。
這樣每次監控,都需要添加一段代碼,因此爲了規範起見。對 XHProf 相關的操做進行了封裝。
繼續採用上例 ThinkPHP 版租車系統的樣例,看看怎樣集成 XHProf 分析。
首先將對 XHProf 的操做封裝成了一個類。
<?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="position:absolute; left:0; top:0; background:orange; padding:8px;">' . '<a href="' . $profiler_url . '" target="_blank">Profiler output</a></p>'; } }
在這個封裝的類中,首先檢測了 xhprof_enable
函數是否存在,這可以用於推斷是否安裝成功配置了 xhprof
擴展。其次設置了參數。特別值得一提的是使用函數 register_shutdown_function
來註冊一個操做,這個操做在頁面結束以前,會本身主動執行。
這樣。在分析頁面性能之時。僅僅需要在 ThinkPHP 應用的 index.php
上加上兩行,即可以了。
比方:
require_once "xhprof.php";
XHProf::init("zuches");
執行後,獲得例如如下效果:
並且每一個頁面。都有這種輸出。點擊「Profiler output」即獲得了報表。
在本例中,可以看到最後的集成方法,執行時間超過了2 S,是值得關注並優化了。從報表中。可以首先看到各個方法或者函數的調用次數,執行時間,以及可以層層點進去看到父子層級的調用關係 。
需要注意的是,在線上。如上使用 XHProf 要謹慎,即便打開,也要有限制條件地打開。比方當前用戶是某些調試開發人員用戶時纔打開。不然,普通用戶看到這種輸出。則不明因此。給用戶帶來困惑。固然,咱們也可以不輸出,而將數據直接存儲,在後臺系統中查看,這樣用戶就感覺不到了。有一個工具,可以全然消除這些糾結。那就是 OneAPM,在第四部分咱們再介紹。
做爲程序猿。除了新功能開發以外,最多見的一個工做就是查錯,尤爲是遠程用戶的查錯,仍是一個很是痛苦的過程。當前又加上了微信開發。API 開發等操做。
對於微信內、API 由遠程用戶所調用的時候,狀況多變。查錯也更加地麻煩。
這個時候。咱們的第三個神器登場了。那就是 SocketLog。
SocketLog 是國內知名 PHP 開發人員羅飛的做品,羅飛是 ThinkPHP 的核心開發人員,也是優才學院全棧project師主力講師。
現任三生社羣 CTO。
SocketLog 的 github 地址爲:https://github.com/luofei614/SocketLog
,在項目的主頁上,具體地介紹了用法和所用的技術。這裏簡單地彙總解說一下。
SocketLog 的使用,主要要分紅三個步驟,第一步是安裝 Chrome 插件。可以從 github 下載的安裝包中去安裝,或者可以從 Chrome 應用商店下載。
第二步是需要啓動 Socket 服務。Socket 服務是 WebSocket 協議的,早期版本號是 PHP 編寫的server。新的版本號已經使用 Node.js 來實現了。
啓動方法很是easy,進入解壓後的文件夾。
執行 node server/index.js
就能夠。
安裝好插件以後。就在 Chrome 上看到例如如下圖標。灰色表示沒有鏈接上。
同一時候啓動了server,作好設置,就會看到圖標變成藍色了。
需要注意的是。雖然咱們這裏監聽地址配置成了本地地址。事實上也可以配置遠程地址。
只是遠程地址的話記得打開server上的防火牆。由於通常1229port在防火牆中是關閉的。
SocketLog 的原理,是在server端,往 WebSocket server上寫數據,做爲client的 Chrome 插件,即能收到數據。因此不論是遠程 API 調用,仍是網頁訪問,僅僅要在程序中往這個 WebSocket server寫了數據,僅僅要監聽了這個 Websocket 服務的client都能收到對應的調試日誌。
第三步是埋代碼。用法也很是easy。比方咱們在上面的 ThinkPHP 的 index.php 加入兩行代碼。
會看到例如如下輸出 。
而後咱們在其它終端上也訪問一下這臺機器的這個頁面地址。看看可否獲得輸出呢?開始沒有不論什麼輸出效果。
由於缺省狀況下是不記錄普通用戶所調用的 slog 的。
在 slog 之上的語句加上這一行,就有了。
slog(array('force_client_id'=>'test'),'set_config');
Test 這個插件的用戶,收到了所有的 slog 消息。例如如下圖所看到的:
並且這種輸出 。不論是別的用戶觸發,而還後臺服務程序。均可以輸出 。
因此很是地方便,開發人員在本身的機器上就收集到了想要收集的用戶所觸發的調試信息。
而後爲了體現對 SQL 語句的監聽。
咱們在 ThinkPHP/Library/Think/Db/Driver.class.php
的第1139行加上 slog($str)
,而後再訪問頁面。就獲得了例如如下輸出 。可見實現了對 SQL 日誌的監控。
SocketLog 的功能看起來雖然簡單,但是卻很是實用、好用。是不可多得的開發神器。有關 SocketLog 的不少其它介紹和使用說明。建議現在就立馬下載,並且進入 github 主頁好好地研究吧!
從上面的使用來看。SocketLog 和 XHProf 都有兩個不足之處,一是需要埋代碼,二是僅僅是基於單獨一個頁面會話的。而 OneAPM 相對來說,就更強大了,可以理解爲雲端 SaaS 版的 XHProf 和更強大的 SocketLog。
只是有着更爲強大的優點。
比方:
OneAPM 的 PHP 探針,安裝完畢以後。並不需要在代碼中埋入不論什麼代碼。
在數據收集的過程當中,不需要開發和運維的參與,探針全本身主動收集。並提交到遠程server。
由於數據累積,因此支持歷史報表。以及比 XHProf 和 SocketLog 更豐富的功能。
PHP 僅僅是 OneAPM 所支持的一種語言,它可以支持多種語言,HTML五、iOS、Android、Java、.NET、python、Node.js、PHP、ruby等。
OneAPM 的安裝過程也比較簡單。只是由於是 SaaS 服務,因此得上官網註冊一個帳號。登陸了以後,在應用程序裏,點擊加入,再選中 PHP。就進入了安裝探針的說明。
分爲例如如下幾步:
1. 獲取受權編號
OneAPM 受權憑證,用於配置和身份識別。
2. 下載 OneAPM PHP agent 安裝程序
3. 解壓 OneAPM PHP Agent
tar -xzf OneAPM_php_Agent_2.3.11.tar.gz
4. 安裝 OneAPM PHP Agent
cd oneapm-php5-linux-install-script
sudo ./oneapm-install install
5. 輸入 License Key
請點擊步驟1中的「生成受權編號button」安裝成功。界面例如如下:
若出現下面信息,則表明安裝成功。
OneAPM is now installed on your system. Congratulations!
當頁面出現下面提示時,啓動 Daemon
And then start php-agent in /usr/bin/oneapm-daemon
執行下面指令來啓動 Daemon
sudo /usr/bin/oneapm-daemon
從新啓動 Apache 或你使用的 web 調度程序 「如 php-fpm 」
6. 靜候5分鐘。開啓 OneAPM 之旅
靜候5分鐘,等待應用程序向 OneAPM 發送應用程序性能數據,就能夠開始使用 OneAPM 應用性能管理。
OneAPM 收集的數據很是豐富。將收集的響應時間數據,分爲四個大塊:
Web 事務,就是頁面業務邏輯自己
數據庫。數據庫的鏈接和數據讀取
錯誤統計,對所有類型的錯誤作了歸類統計
外部服務,即外部 API 等的設備
以筆者的站點爲例,12小時的數據例如如下圖:
從上面這個圖,咱們看到響應時間,慢的達到了600 ms 以上,那是什麼致使的呢?咱們可以分別查看:
可見 Web 事務比較穩定,可以比較清楚地看到平均的響應時間在 50ms-75ms之間。
數據庫響應時間也很是短,在幾 ms 這個級別。而外部服務就明顯在幾百 ms 這個級別。還有的高達 600 ms 。
不說別的。就經過這簡單的報表,從眼下看,就可以定位到,想要作優化,從外部服務的響應時間上下手優化,帶來的效果是最大的。
下面咱們再來看看三個細化一層的報表 ,在 Web 事務統計中。雖然平均數很是低,但是也列出了響應時間最長的5個請求。
例如如下:
從上面的數據可以看出,響應時間最長的幾個,主要突出在 bind.php
,這個是負責 QQ 登陸的請求。需要向騰訊請求數據。
而在數據庫一欄中,可以看到最慢的5個表格的狀況。
在外部的服務中,果不出所料,是對微博、微信、QQ 登陸、七牛上傳、支付寶通知等外部服務。所佔時間最長。
例如如下圖所看到的。
這僅僅是普通的統計報表,對於具體的某一個慢的頁面,更有具體的調用分析。
比方上面的 bind.php
,果然最慢的是從網絡上獲取數據。也就是說,第三方登陸時。從第三方站點取數據花了絕大部分時間。 去查看詳情,有兩個不足之處,一是需要埋代碼,二是僅僅是基於單獨一個頁面會話的。而 OneAPM 稱爲慢事務追蹤,拉到頁面的最底部就能看到。
在後臺報表中。咱們相同也能看到是哪些 SQL 語句慢。比方例如如下是 bind.php
中慢的 SQL 語句。
更爲重要的是,還有所有錯誤信息的收集,也一目瞭然。
因此無論從功能之強大,仍是易用之方便,有兩個不足之處,一是需要埋代碼,二是僅僅是基於單獨一個頁面會話的。而 OneAPM 不愧是商業化的 SaaS 服務,比 XHProf 勝去了很多。在筆者的項目中。已經大量使用。並取得了好的效果。
以上四個項目,讓咱們對本身所寫的代碼。更加胸有成竹,不論是執行過程仍是調優着手了都有了充分的把握。
特地對照,彙總整理的這四大神器,但願它們能改善每一位 PHP 開發人員的生活,讓咱們的 PHP 開發再也不那麼地苦逼!