最近老高发现服务器的CPU总是被某个php-fpm占用过高,记录一下如何排查。
发现
如何发现的呢?当然是使用top
命令,发现系统的load average>3,这说明系统已经处于比较高的负载中。
尝试解决
当我把php-fpm重启后,没过一会儿又开始cpu狂飙!这是什么鬼?
开始排查
首先,我们开启在php-fmp.conf中开启错误日志,慢执行日志还有常规日志
error_log = /var/log/php/error.log | |
access.log = /var/log/php/access.$pool.log | |
access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %{system}C%%" | |
slowlog = /var/log/php/slow.$pool.log | |
request_slowlog_timeout = 3s |
重启php-fpm后我们开始监视日志
[1819 | ] [pool www] pid|
script_filename = /home/ftp/phpergao/wwwroot/index.php | |
[72 | ] replace() /home/ftp/phpergao/wwwroot/usr/plugins/CdnHelper/Plugin.php:|
[0 | ] replace() unknown:|
[var/Typecho/Plugin.php:489 | ] call_user_func_array() /home/ftp/phpergao/wwwroot/|
[0 | ] __call() unknown:|
[var/Widget/Abstract/Contents.php:141 | ] contentEx() /home/ftp/phpergao/wwwroot/|
[var/Typecho/Widget.php:385 | ] ___content() /home/ftp/phpergao/wwwroot/|
[0 | ] __get() unknown:|
[var/Widget/Abstract/Contents.php:783 | ] content() /home/ftp/phpergao/wwwroot/|
[var/Widget/Archive.php:1401 | ] content() /home/ftp/phpergao/wwwroot/|
[32 | ] content() /home/ftp/phpergao/wwwroot/usr/themes/just/index.php:|
[ | ] +++ dump failed|
[5597 | ] [pool www] pid|
script_filename = /home/ftp/phpergao/wwwroot/index.php | |
[var/Typecho/Plugin.php:483 | ] __call() /home/ftp/phpergao/wwwroot/|
[0 | ] __call() unknown:|
[var/Typecho/Widget.php:387 | ] ___title() /home/ftp/phpergao/wwwroot/|
[0 | ] __get() unknown:|
[var/Widget/Abstract/Contents.php:809 | ] title() /home/ftp/phpergao/wwwroot/|
[23 | ] title() /home/ftp/phpergao/wwwroot/usr/themes/just/index.php:|
[ | ] +++ dump failed
其中contentEx引起了我的注意,这个方法是一个钩子,系统在获取到文章内容后执行,老高的有几个插件都挂载在此,突然就有想法了。
于是立即暂停有关的插件,过一阵负载变为load average: 0.39, 0.29, 0.42。
记录程序运行细节
记录程序运行时间
$start = microtime(true); | |
//index.php | |
$end = microtime(true); | |
$time = number_format(($end - $start), 2); | |
echo 'This page loaded in ', $time, ' seconds'; | |
跟踪php的系统调用
老高使用strace查看php主进程以及fork出的子进程的系统调用,并输出到/tmp/output.txt
strace -o /tmp/output.txt -T -tt -F -e trace=all -p 31920
将输出的文件用scp拷贝到本地电脑上,经过分析,并发+插件几乎拖死了CPU。
结论
- 某些数据的展示与否最好把性能也考虑上
- 正则的效率不高,能不用尽量不用
- 主题中如果同一个变量要使用多次,请将其先保存至一个临时变量
- 缓存很重要
- strace是个好工具