php性能调优

发表于2014-08-19 19:57  |  次阅读  |  0条评论  |   作者:admin

最近对php性能调优比较感兴趣,所以跟踪了一下线上服务,做了一些测试,有一些结论,写出来做备忘啦。

我这次的优化针对syscall调用过多的问题,所以使用strace跟踪apache进行分析。

1.  apache2ctl -X &

使用-X(debug)参数启动httpd进程,这个时候只启动1个httpd进程

2. ps -ef | grep httpd

找到需要strace的pid

3. strace -p $PID -o /tmp/strace.log

发送一个http请求到httpd,就能看到strace信息了。

 

一、include_path问题

一般可以看到很多这类信息:

stat64("/error/dir/test.php", 0xbfab4b9c) = -1 ENOENT (No such file or directory)

解决方法:

1. 在应用php里面设置include_path,去掉'.'等相对路径,将其中包含使用文件比较多的目录放到前面。保证遍历include_path的时候能够很快找到。

2. 使用绝对路径进行include,require,include_once,require_once

3. 使用php的自动加载机制

 

二、apache的rewrite配置

    RewriteEngine On

    RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
    RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
    RewriteRule .* %{DOCUMENT_ROOT}%/index.php

   #RewriteRule .* /index.php 

这里最后一个注释掉的rewrite配置不好,因为它每次请求都会多一次syscall

stat64("/index.php", 0xbfab4b9c) = -1 ENOENT (No such file or directory)

 

三、apache日志问题

我们在测试一个问题的时候,发现如果自定义日志里面记录了访问时间等信息,会多出很多

stat64("/etc/localtime", {st_mode=S_IFREG|0644, st_size=165, ...}) = 0

如果记录的日志比较多,性能下降非常严重,对于简单应用,记录复杂日志,性能会下降30倍。

解决方法:

在多个apache前端架http层的proxy,如haproxy,nginx。在这些地方记录日志。接入层负载一般不高,所以proxy可以做一些记录日志的工作。在这种配置下,可以关闭apache的日志

 

三、realpath()问题

大家可以看一下这篇文章:http://bugs.php.net/bug.php?id=43864

lstat64调用多了之后,主机CPU和IO都会比较高。

究其原因,因为php5.2.x对realpath()的实现不够好,导致会针对目录层次,逐级调用lstat64()。

为了解决这个问题,它使用了realpath_cache,针对某个文件,存储其realpath。这里只存储了叶子节点的realpath,而对 路径上的内容没有存储,所以在做"/a/b/c/d/e/f/g/a.php"realpath检查的时候逐级调用lstat64,而在做"/a/b/c /d/e/f/g/b.php"检查的时候,还要对""/a/b/c/d/e/f/g/"做逐级检查。所以有些优化建议就是“减少目录层次,甚至放到"/"根目录下”。当然我不推荐这么干。从5.3.0开始,php对realpath()做了高效的实现,路realpath的中间路径也做了缓存,以上面的情况为例,检查"/a/b/c/d/e/f/g/b.php"的时候就只会做“b.php”的检查了。所以,升级到php5.3.0以上版本能够很好地解决这个问题。

解决方法:

1. 尽量少用include_once和require_once

因为这两个函数会做realpath检查,防止有符号链接的情况导致重复加载。不用它们就能减少realpath的调用。

2. 合理设定php.ini中的realpath_cache_size和realpath_cache_ttl参数

既然使用了realpath_cache,那肯定有大小限制。对于使用了很多文件,比如用了Zend Framework的项目,可能默认realpath_cache_size=16k就太小了,需要增大这个设置,推荐设置为256K以上。另外默认realpath_cache_ttl=120,2分钟就过时了,怎么也要设定为3600(1小时)啊。

这里需要注意的是,这个realpath_cache是每隔apache进程独占的,所以很吃内存的,不能设置的太大。

3. 升级到php5.3.x

没什么好说的,如果应用经过详细测试没有问题,那么推荐升级到高版本。

 

四、APC的使用

apc能够缓存php的opcode码,能普遍提升30%的性能。但是默认apc.stat=1,这样每次请求都会访问需要使用的php文件,看看这个文件是否更新了,已决定是否重新编译php文件。这个是很耗性能的,推荐关掉。

解决方法:

1. 设定apc.stat=0,不必每次请求都访问需要用到的php文件。

需要注意的是:每次发版本改动了php文件的时候,必须调用apc_clear()清除apc缓存,否则你的代码永远也不会生效。

五、smarty调优

对于模块化比较好,而且应用比较多的网站,如果使用了smarty模板系统,这个时候就需要对smarty进行调优了,否则smarty部分的开销就很可观。之前根据一个经验来看,smarty可以占到10%左右的开销。

默认配置下,smarty对检测每个模板文件是否有更新,决定是否重新编译模板文件。如果模板文件比较多,则会多出很多stat系统调用,加上context switch,开销会不小。

解决方法

1. $smarty->compile_check = false;
去掉每次的检测,但是这样之后,每次发版本都要把compile_dir目录的已编译模板删除,否则你的模板文件永远也不会生效了。
2. 如果可能,可以使用cache功能。

 

结论

经过上面的调优,结论如下:

  1. 升级到php5.3.1开启上面的优化,比5.2.3性能高10%以上
  2. 在优化配置下,使用Zend Framework开发的一个搜索应用,每秒请求可达210/rps
  3. 在优化配置下,使用doophp framework开发的一个搜索应用,每秒请求可达450/rps

本站关键字:sunny90 web开发 数据库 移动开发 服务器 Nginx Mysql PHP
Copyright © sunny90版权所有 power by sunny90.com  
湘ICP备14012284号-1,粤公网安备 44030602000307号