PHP7 安裝 xhprof

wwulfric發表於2017-11-29

原文地址:PHP7 安裝 xhprof

xhprof 是 Facebook 09 年出的一個很優秀的 PHP profiler 工具,但 Facebook 後來遷移到 hhvm,早已不再維護,它在 PHP7 下有諸多 bug。

使用相容的 xhprof 安裝

xhprof已經很久沒有更新了,使用他人的repo[^1]:

cd ~
git clone https://github.com/longxinH/xhprof
cd xhprof/extension/複製程式碼

查詢 php7 下的 phpize 的位置。

which php71 # 檢視 php71 的位置
ll /usr/bin/php71 # 檢視軟連結的位置
ls /opt/remi/php71/root/usr/bin/ # 檢視所有命令複製程式碼

安裝外掛。

/opt/remi/php71/root/usr/bin/phpize
./configure --with-php-config=/opt/remi/php71/root/usr/bin/php-config  --enable-xhprof
sudo make
sudo make install複製程式碼

重啟 php-fpm。

sudo service php71-php-fpm restart
php71 -m | grep xhprof複製程式碼

此時,安裝成功。我們配置一下 xhprof 外掛:

[xhprof]
extension=xhprof.so;
xhprof.output_dir=/var/tmp/xhprof複製程式碼

其中 xhprof.output_dir 是 xhprof 的輸出目錄,每次執行 xhprof 的 save_run 方法時都會生成一個 run_id.project_name.xhprof 檔案。這個目錄在哪裡並不重要。

nginx 配置訪問

當生成 .xhprof 檔案之後,我們就可以利用 xhprof_lib 來展示結果了。

建立資料夾 /var/www/html/xhprof,然後配置 nginx 如下[^2]:

server {
    listen 80;
    root /var/www/html/xhprof/;
    server_name your_host;
    location = / {
        index 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;
    }
}複製程式碼

在 /var/www/html/xhprof/xhprof_html 下建立 index.php

<?php
    echo phpinfo();
?>複製程式碼

訪問 http://your_host/index.php 檢視是否正確顯示 phpinfo。

當配置成功之後,將 xhprof 中的 xhprof_lib 和 xhprof_html 兩個資料夾複製到 /var/www/html/xhprof/ 下,然後訪問 http://your_host/xhprof_html/index.php 即可。

PS: 安裝 yum install graphviz 檢視圖形介面。

修改 nginx 配置中的 root 直接指向 xhprof_html,配置如下:

server {
    listen 80;
    root /var/www/html/xhprof/xhprof_html;
    server_name your_host;
    location = / {
        index 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_html 下已經有 index.php 了,所以可以直接訪問 http://your_host。

# nginx 指向的路徑
$ ls /var/www/html/xhprof
footer.php  header.php  index.php  xhprof_html  xhprof_lib

# xhprof 儲存的資料
$ ls /var/tmp/xhprof
5979c9dfe223a.your_project.xhprof  597aae1684192.your_project.xhprof複製程式碼

使用方法

和之前一樣,將要檢查效能的程式碼包裹起來就可以了。

<?php
xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);

// 要檢查效能的程式碼

$xhprof_data = xhprof_disable();
include_once  '/var/www/html/xhprof/xhprof_lib/utils/xhprof_lib.php';
include_once  '/var/www/html/xhprof/xhprof_lib/utils/xhprof_runs.php';
$xhprof_runs = new \XHProfRuns_Default();
$run_id = $xhprof_runs->save_run($xhprof_data, 'your_project');複製程式碼

當然這裡也可以將前後的程式碼單獨開一個php檔案:header.php 和 footer.php。

// header.php
<?php
if (extension_loaded('xhprof')) {
    include_once 'xhprof_lib/utils/xhprof_lib.php';
    include_once 'xhprof_lib/utils/xhprof_runs.php';
    xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);
}
?>複製程式碼
// footer.php
<?php
if (extension_loaded('xhprof')) {
    $profiler_namespace = 'your_project';
    $xhprof_data = xhprof_disable();
    $xhprof_runs = new XHProfRuns_Default();
    $run_id = $xhprof_runs->save_run($xhprof_data, $profiler_namespace);
}
?>複製程式碼

然後用這兩個檔案包裹程式碼。如果是 Apache,可以在專案的 .htaccess 檔案中新增:

#php_value auto_prepend_file /var/www/html/xhprof/header.php
#php_value auto_append_file /var/www/html/xhprof/footer.php複製程式碼

如果是 nginx + php-fpm,可以在php-fpm.d/www.conf 新增:

php_value[auto_prepend_file] = /var/www/html/xhprof/header.php
php_value[auto_append_file] = /var/www/html/xhprof/footer.php複製程式碼

個人還是更喜歡在需要的地方手動 require:

<?php
include_once  '/var/www/html/xhprof/header.php';

// 要檢查效能的程式碼

include_once  '/var/www/html/xhprof/footer.php';複製程式碼

這樣更加靈活,而且不會每個請求都生成一份報告,只在需要的時候生成。

Notice

  1. 如果遇到錯誤 failed to execute cmd: " dot -Tpng". stderr: ` (process:24220): Pango-WARNING **: Invalid UTF-8 string passed to pango_layout_set_text() '。暫時不清楚怎麼解決,可以選擇避開它。將 xhprof_lib/utils/callgraph_utils.php 的 121,122 行的列印和 exit 註釋掉。
  2. 如果遇到錯誤 Error: either we can not find profile data for run_id xxx or the threshold 0.01 is too small or you do not have 'dot' image generation utility installed,無法生成 png 圖片,可能是因為生成的檔案中有不能識別的字元,修復如下[^3]:
    $cmd = " dot -T".$type;
    // 在 cmd 之後新增一個轉碼工作就可以了
    $dot_script = iconv("UTF-8", "ASCII//IGNORE", $dot_script);複製程式碼
  3. 如果想要更好看的 UI,可以參考以下連結1連結2連結3 (手動搭免費)。
  4. 下面是一些引數說明
效能點 描述
Inclusive Time 包括子函式所有執行時間
Exclusive Time/Self Time 函式執行本身花費的時間,不包括子樹執行時間
Wall Time 花去了的時間或掛鐘時間
CPU Time 使用者耗的時間 + 核心耗的時間
Inclusive CPU 包括子函式一起所佔用的 CPU
Exclusive CPU 函式自身所佔用的 CPU

[^1]: xhprof issue某博文提到了一些替代 repo,除此之外還有 tideways
[^2]: nginx 的配置參考了 某 gitbooknginx wiki
[^3]: 這個在網上很難找到解決方案,我在 PHP 的 bug 平臺找到了它:連結

相關文章