暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

PHP-FPM资源占用过高的分析经历

金色稻田 2016-08-25
789

最近发现接口项目的服务器上,fpm进程的CPU使用率忽高忽低。根据以前的项目经验,类似情况最后都发现接口里存在严重性能问题的代码,所以我们立马动手分析一下吧。

症状

服务器上top,不管是高峰期还是低峰期,CPU使用率忽高忽低。


排查

首先查看了php的错误日志和慢日志,发现没有任何记录。


回到top查看系统状态,按数字键1,每个核的负载情况如下图。


发现用户空间占用CPU百分比比较高(us),安装ltrace开始跟踪FPM进程的库函数调用。如果是内核空间占用CPU百分比比较高(sy),则使用strace。

ltrace -c -p $(pgrep -n php-fpm)

如下图结果,memcpy调用有点夸张,这时还只是认为因部分接口里列表数据比较大,每个数据的字段又循环赋值很多次导致的。


还有没有其他方面的原因?!使用ltrace查看php的一个进程的系统调用,并输出到/tmp/output.txt。

ltrace -o tmp/output.txt -T -p $(pgrep -n php-fpm)

下载output.txt文件到本地分析也没有发现其他异常的库函数调用。


继续分析,接下来准备查看一下项目里的PHP代码性能。到一台线上服务器安装xhprof,修改入口文件。


index.php添加以下代码。

if (function_exists('xhprof_enable')) {
   // 如果使用xhprof_enable(XHPROF_FLAGS_MEMORY | XHPROF_FLAGS_CPU);报502错误,使用下面的设置    xhprof_enable(XHPROF_FLAGS_NO_BUILTINS | XHPROF_FLAGS_CPU | XHPROF_FLAGS_MEMORY); }

register_shutdown_function里添加以下代码。

if (function_exists('xhprof_enable')) {
   $data = xhprof_disable();
   include_once "/data/src/xhprof-0.9.4/xhprof_lib/utils/xhprof_lib.php";
   include_once "/data/src/xhprof-0.9.4/xhprof_lib/utils/xhprof_runs.php";
   $objXhprofRun = new XHProfRuns_Default();
   $objXhprofRun->save_run($data, "xhprof"); }

两分钟后关闭xhprof扩展,下载所有收集的数据,在本地使用xhprof的图表模式查看收集的数据。


完整调用图如下。可以看到,大部分的接口里(但并不是所有),ApiData::encrypt比较耗时。




结论

到此,终于。。。大概。。。找到了问题。在我们的接口系统里,数据加密方法会对接口返回的数据每个字节进行加密操作。这也解释了为什么有时ltrace记录里memcpy操作次数会那么夸张,而且并不是所有接口都是encrypt最耗时。因为只有接口返回的数据比较大的时候才会出现。


继续验证,写了个PHP脚本测试加密算法,加密20KB的数据,耗时6ms,而使用C语言,0.1ms不到。。。


那么,在不能改变算法的情况下,解决办法是用C语言写个PHP扩展?

文章转载自金色稻田,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论