前几天有位朋友在公众号问我,Deliverer
和 Xhprof
有什么区别吗?一句话:Xhprof
是一个排查性能问题的工具,为系统性能做保障;Deliverer
是一个排查 Bug 的工具,为系统可用性服务。
适用场景
Xhprof
Xhprof
是一个排查性能问题的工具,为系统整体性能做保障。比如
发现某个接口比较慢,为了能够更清楚的找到性能瓶颈,则可以这样配置php.ini
配置
extension=xhprof.so
xhprof.output_dir=/tmp/xhprof
auto_prepend_file=/var/www/mengkang.test/header.php
auto_append_file=/var/www/mengkang.test/footer.php
/var/www/mengkang.test/footer.php
的具体代码可以是
$xhprof_data = xhprof_disable();
$total_time = $xhprof_data["main()"]["wt"];
$total_time = round($total_time/1000,2);
$XHPROF_ROOT = __DIR__;
include_once $XHPROF_ROOT . "/xhprof_lib/utils/xhprof_lib.php";
include_once $XHPROF_ROOT . "/xhprof_lib/utils/xhprof_runs.php";
$xhprof_runs = new XHProfRuns_Default('/tmp/xhprof');
$run_id = $xhprof_runs->save_run($xhprof_data, "test");
$trace_id = isset($GLOBALS['rpc_trace_id']) ? $GLOBALS['rpc_trace_id'] : "";
$XHPROF_URL='http://mengkang.test/xhprof_html/index.php?time='.$total_time.'&run='.$run_id.'&source=test&trace_id='.$trace_id;
file_put_contents("/tmp/xhprof".date('Ymd').".log",$XHPROF_URL."\n",FILE_APPEND);
其中rpc_trace_id
是各个系统自己透传的,方便定位上下游的链路。同时接口的返回值中都会带上这个 requestId
(rpc_trace_id),如此之后则再访问 http://mengkang.test/xhprof_html/index.php?time=xxx&run={run_id}&source=test&trace_id=xxx 来跳转到run_id
对应的 xhprof 的分析报告上。
还有类似的场景就是针对线上,指定阈值的慢请求(比如响应时间超过 3s)才进行$xhprof_runs->save_run
,如果怕有性能损耗,可以抽样或者排重,看业务容忍度。
另一方面,如果业务逻辑中存在 bug 或者写了 exit 代码,最后导致这个性能采集失效,当然可以尝试下通过监听系统信号量的方式来主动调用footer.php
的代码。
而且 xhprof 的调用链的查看方式依赖层层点击,不太利于分析。这不是它的缺点,只是说明下这不是它想解决的问题场景
Deliverer
Deliverer
是一个排查 Bug 的工具,为系统可用性服务。在不使用 Deliverer
的情况下,只能使用 strace
来根据系统调用的情况来排查问题,一方面系统调用日志繁杂、特别多;另一方面,看到的都是系统调用的函数,需要反推出在 php 里面的函数或者方法,需要有经验的猜。
因为 php-fpm
子进程也是常驻的,用strace
跟的时候,每个请求的日志也是不分割的,查看起来比较麻烦,并且不知道请求的上下文,针对使用strace
遇到的这些小问题,以上就是Deliverer
的设计初衷。
https://github.com/zhoumengkang/deliverer
https://gitee.com/zhoumengkang/deliverer
如何安装使用见该项目的 readme
既然是了排查 bug 而生,Deliverer
不仅仅局限于php-fpm
模式下的环境,不管是什么入口,只需要监听过滤指定的文件、方法、类名、函数即可。会在日志最前面一行打印 pid、ts、sapi、http 信息、cli 参数,方便我们追踪定位问题的源头。
性能
在数据日志的采集上略有不同,Deliverer
性能损耗更小,因为Xhprof
是将 PHP 的zend_execute
和zend_execute_ex
包裹一层。而Deliverer
是在opcode
执行环节中,针对特定的opcode
类型做处理,调用次数要少一些,但是都这都是微乎其微的差别。
同时Deliverer
只会在开启监听(下载压缩包之后,执行./bin/deliverer -t
)之后才会生效,否则是不会采集日志的,所以线上提前安装也没有问题,只要不开启监听,不会有任何性能损耗。
最后
场景不一样而已,xhprof 是一个非常棒的工具,并没有黑它的意思。Deliverer
已支持 PHP5 和 PHP7.