使用XHProf分析PHP性能瓶頸(一)


安裝xhprof擴展

wget http://pecl.php.net/get/xhprof-0.9.4.tgz
tar zxf xhprof-0.9.4.tgz
cd xhprof-0.9.4/extension/
sudo phpize
./configure
sudo make
sudo make install
cd ../

配置php.ini

[xhprof]
extension=xhprof.so
xhprof.output_dir=/tmp

注:xhprof已經很久沒有更新過了,截至目前還不支持php7,php7可以使用 https://github.com/phacility/xhprof.git。

配置xhprof環境

需要把xhprof壓縮包里的兩個目錄復制到指定目錄(假設定義到 /work/xhprof/):

mkdir /work/xhprof/
cp -a xhprof_html/ /work/xhprof/
cp -a xhprof_lib/ /work/xhprof/

然后在項目框架的入口文件添加:

xhprof_enable(XHPROF_FLAGS_MEMORY | XHPROF_FLAGS_CPU);
register_shutdown_function(function() {
    $xhprof_data = xhprof_disable();
    if (function_exists('fastcgi_finish_request')){
        fastcgi_finish_request();
    }
    include_once "/work/xhprof/xhprof_lib/utils/xhprof_lib.php";
    include_once "/work/xhprof/xhprof_lib/utils/xhprof_runs.php";
    $xhprof_runs = new XHProfRuns_Default();
    $run_id = $xhprof_runs->save_run($xhprof_data, 'xhprof');
});

代碼解析:
$xhprof_data中記錄了程序運行過程中所有的函數調用時間及CPU內存消耗,具體記錄哪些指標可以通過xhprof_enable的參數控制,目前支持的參數有:

  • HPROF_FLAGS_NO_BUILTINS 跳過所有內置(內部)函數。
  • XHPROF_FLAGS_CPU 輸出的性能數據中添加 CPU 數據。
  • XHPROF_FLAGS_MEMORY 輸出的性能數據中添加內存數據。

之后的處理已經與xhprof擴展無關,大致是編寫一個存儲類XHProfRuns_Default,將$xhprof_data序列化並保存到某個目錄,可以通過XHProfRuns_Default(__DIR__)將結果輸出到當前目錄,如果不指定則會讀取php.ini配置文件中的xhprof.output_dir,仍然沒有指定則會輸出到/tmp

xhprof_enablexhprof_disable是成對出現的,一個是代碼運行最前面,一個是最后面。中間是要分析的代碼。

經過上面的配置后,我們后續請求項目的接口,xhprof就會分析請求過程中的CPU、內存、耗時等內容。日志保存在xhprof.output_dir目錄。

配置web

配置好了,怎么查看日志呢?我們可以搭建一個簡單的web server:

xhprof.test.com.conf

server {
    listen       80;
    server_name  xhprof.test.com;

	root /work/xhprof/xhprof_html;
	index  index.html index.php;


    location ~ \.php$ {
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
}

然后配置虛擬主機xhprof.test.com。重啟nginx,打開 xhprof.test.com就可以看到效果了:


默認的UI里列出了:

  • funciton name : 函數名
  • calls: 調用次數
  • Incl. Wall Time (microsec): 函數運行時間(包括子函數)
  • IWall%:函數運行時間(包括子函數)占比
  • Excl. Wall Time(microsec):函數運行時間(不包括子函數)
  • EWall%:函數運行時間(不包括子函數)

在web中還可以看到 [View Full Callgraph] 鏈接,點擊后可以繪制出一張可視化的性能分析圖,如果點擊后報錯的話,可能是缺少依賴graphviz。graphviz是一個繪制圖形的工具,可以更為直觀的讓你查看性能的瓶頸。如果需要可以安裝:

yum install -y libpng
yum install -y graphviz

效果:

非侵入式引入xhprof

前面我們是通過在項目入口文件添加代碼實現了分析的功能。更優雅的方式是新建一個額外的文件 xhprof.inc.php,保存在/work/xhprof/目錄下:

xhprof_enable(XHPROF_FLAGS_MEMORY | XHPROF_FLAGS_CPU);
register_shutdown_function(function() {
    $xhprof_data = xhprof_disable();
    if (function_exists('fastcgi_finish_request')){
        fastcgi_finish_request();
    }
    include_once "/work/xhprof/xhprof_lib/utils/xhprof_lib.php";
    include_once "/work/xhprof/xhprof_lib/utils/xhprof_runs.php";
    $xhprof_runs = new XHProfRuns_Default();
    $run_id = $xhprof_runs->save_run($xhprof_data, 'xhprof');
});

利用PHP的自動加載功能,在執行代碼前注入此文件,編輯php.ini:

auto_prepend_file = /work/xhprof/xhprof.inc.php

然后重啟PHP服務。這樣所有使用該php環境的都會生效。

或者寫到指定項目的nginx配置里也行:
jifen.cc.conf

location ~ \.php$ {
        
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
	fastcgi_param PHP_VALUE "auto_prepend_file=/work/xhprof/xhprof.inc.php";
        include        fastcgi_params;
    }

然后重啟nginx服務。這樣僅該項目生效。

通過 auto_prepend_file 和 auto_append_file包含的文件在此模式下會被解析,但有些限制,例如函數必須在被調用之前定義。

修改采樣頻率

默認情況下,xhprof每次都會運行,線上環境如果這么設置,會對性能有影響。

xhprof.inc.php

<?php
$profiling = !(mt_rand()%9); 
if($profiling) xhprof_enable(XHPROF_FLAGS_MEMORY | XHPROF_FLAGS_CPU);
register_shutdown_function(function() use($profiling) {
    if($profiling){
		$xhprof_data = xhprof_disable();
		if (function_exists('fastcgi_finish_request')){
			fastcgi_finish_request();
		}
		include_once "/work/xhprof/xhprof_lib/utils/xhprof_lib.php";
		include_once "/work/xhprof/xhprof_lib/utils/xhprof_runs.php";
		$xhprof_runs = new XHProfRuns_Default();
		$xhprof_runs->save_run($xhprof_data, 'xhprof');	
	}
});

總結

本篇文章里,我們介紹了如何基於xhprof擴展來分析PHP性能,並記錄到日志里,最后使用xhprof擴展自帶的UI在web里展示出來。主要知識點:

  • 安裝xhprof擴展
  • 在應用里注入xhprof
  • 基於nginx展示分析結果

參考

1、Xhprof 的配置和使用方法 - 簡書
https://www.jianshu.com/p/38e3ae81970c
2、使用XHProf查找PHP性能瓶頸 - 程序猿成長計划 - SegmentFault 思否
https://segmentfault.com/a/1190000003509917
3、PHP性能追蹤及分析工具xhprof的安裝與使用 - 馬新才的技術博客 - SegmentFault 思否
https://segmentfault.com/a/1190000007288664
4、Tideways和xhgui打造PHP非侵入式監控平台 | 我是大熊
http://blog.it2048.cn/article-tideways-xhgui/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM