保护私人版权,尊重他人版权。转载请注明出处并附带页面链接
分析php的系统调用
前言
某一天,突然发现cpu占用特别高,top了一下发现是php导致的。那应该怎么去处理呢?
尝试去解决
查看日志,日志也没报错。
只能把php-fpm重启了,cpu早降下来了。可是才一阵子,cpu又飙上来了。
使用strace去跟踪php的调用
starce的安装
1 | yum install strace |
strace 指令的使用,这里就不多解释了。
模拟多次读写文件
代码
1 | for ($i= 0 ; $i < 50000; $i ++) { |
如下,cpu使用率一下就上来了。
使用 strace -c -p 25792(此数字为跑上面代码的脚本的pid),结果如下:
可以看得出有大量的 lseek、open、write、close等的系统调用。
1 | lseek:lseek函数可以改变文件的cfo。所有打开的文件都有一个当前文件偏移量(current file offset),简称为 cfo。读写操作通常开始于 cfo,并且使 cfo增大,增量为读写的字节数。 |
可能使用以下命令,获取更详细的结果:
1 | strace -o /tmp/strace_output.log -T -tt -F -e trace=all -p 25792 |
结果如下:
↑↑↑↑↑ 会发现上图大量这样的重复的日志,因为上面的测试的代码就是不断这样的读写,以及关闭文件。
↑↑↑↑↑ 到最后,会有释放内存映射这样的操作,从上图开始到下图的结束,总共耗时了30s多。
总结:尽量少进行文件操作,以及注意文件的打开和关闭。
模拟多次连接数据库并读取
代码
1 | for ($i= 0 ; $i < 5000; $i ++) { |
1 | recvfrom:接受信息 |
从上图可以看出,有大量的连接和关闭的操作,这也是很消耗系统资源的。
部分详细结果如下:
↑↑↑↑↑ 会发现上图大量不断的连接、发送、接收、关闭等的操作,相当消耗系统资源。
总结:像上面这样的操作是相当消耗资源,而且还会影响到数据库机器的性能。比如要注意,数据库实例使用单例,不要不断建立连接,关闭连接。也可以使用一些数据库的中间件,减少与数据库机器的连接。
总结
- 在实际中,不仅仅是php,其他的进程也可以使用strace查看系统调用,而进行优化。
- 代码该做的优化还是得做,如读写文件,数据库的操作。
- 当遇上性能问题时,排查日志无法解决时,可以查看整个详细结果,可以查看一整段时间消耗在哪里。