首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > PHP >

Nginx+PHP-FPM优化技巧总结

2013-10-08 
【原创】Nginx+PHP-FPM优化技巧总结php-fpm的安装很简单,参见PHP(PHP-FPM)手动编译安装。下面主要讨论下如何

【原创】Nginx+PHP-FPM优化技巧总结
php-fpm的安装很简单,参见PHP(PHP-FPM)手动编译安装。下面主要讨论下如何提高Nginx+Php-fpm的性能。
1.Unix域Socket通信
之前简单介绍过Unix Domain Socket这种通信方式,参见:Nginx+PHP-FPM的域Socket配置方法
Unix域Socket因为不走网络,的确可以提高Nginx和php-fpm通信的性能,但在高并发时会不稳定。Nginx会频繁报错:     connect() to unix:/dev/shm/php-fcgi.sock failed (11: Resource temporarily unavailable) while connecting to upstream
可以通过下面两种方式提高稳定性:1)调高nginx和php-fpm中的backlog     配置方法为:在nginx配置文件中这个域名的server下,在listen 80后面添加default backlog=1024。     同时配置php-fpm.conf中的listen.backlog为1024,默认为128。2)增加sock文件和php-fpm实例数     再新建一个sock文件,在Nginx中通过upstream模块将请求负载均衡到两个sock文件背后的两套php-fpm实例上。

2.php-fpm参数调优
2.1进程数
php-fpm初始/空闲/最大worker进程数     pm.max_children = 300     pm.start_servers = 20     pm.min_spare_servers = 5     pm.max_spare_servers = 35
2.2最大处理请求数
最大处理请求数是指一个php-fpm的worker进程在处理多少个请求后就终止掉,master进程会重新respawn一个新的。这个配置的主要目的是避免php解释器或程序引用的第三方库造成的内存泄露。     pm.max_requests = 10240
2.3最长执行时间
最大执行时间在php.ini和php-fpm.conf里都可以配置,配置项分别为max_execution_time和request_terminate_timeout。其作用及其影响参见:Nginx中502和504错误详解

3.php-fpm的高CPU使用率排查方法
3.1CPU使用率监控方法
1)top命令直接执行top命令后,输入1就可以看到各个核心的CPU使用率。而且通过top -d 0.1可以缩短采样时间。下面的sar貌似最短只能是1秒。
2)sar命令sar和iostat命令的安装:     sysstat.x86_64 : The sar and iostat system monitoring commands     yum install -y sysstat.x86_64
执行sar -P ALL 1 100。-P ALL表示监控所有核心,1表示每1秒采集,100表示采集100次。输出结果如下:CPU     %user     %nice   %system   %iowait    %steal     %idleall     85.54      0.00      5.69      0.00      0.00      8.76  0     74.75      0.00     25.25      0.00      0.00      0.00  1     98.00      0.00      2.00      0.00      0.00      0.00  2     89.22      0.00      3.92      0.00      0.00      6.86  3     91.00      0.00      2.00      0.00      0.00      7.00  4     75.00      0.00      9.00      0.00      0.00     16.00  5     94.95      0.00      5.05      0.00      0.00      0.00  6     95.00      0.00      4.00      0.00      0.00      1.00  7     87.88      0.00      4.04      0.00      0.00      8.08  8     93.94      0.00      3.03      0.00      0.00      3.03  9     88.00      0.00      3.00      0.00      0.00      9.0010     89.11      0.00      2.97      0.00      0.00      7.9211     82.35      0.00      3.92      0.00      0.00     13.7312     73.27      0.00      7.92      0.00      0.00     18.8113     81.44      0.00      4.12      0.00      0.00     14.4314     77.23      0.00      6.93      0.00      0.00     15.8415     78.79      0.00      4.04      0.00      0.00     17.17
3.2开启慢日志
配置输出php-fpm慢日志,阀值为2秒:

request_slowlog_timeout = 2
slowlog = log/$pool.log.slow

利用sort/uniq命令分析汇总php-fpm慢日志:[root@b28-12 log]# grep -v "^$" www.log.slow.tmp | cut -d " " -f 3,2 | sort | uniq -c | sort -k1,1nr | head -n 50   5181 run() /www/test.net/framework/web/filters/CFilter.php:41   5156 filter() /www/test.net/framework/web/filters/CFilterChain.php:131   2670 = /www/test.net/index.php   2636 run() /www/test.net/application/controllers/survey/index.php:665   2630 action() /www/test.net/application/controllers/survey/index.php:18   2625 run() /www/test.net/framework/web/actions/CAction.php:75   2605 runWithParams() /www/test.net/framework/web/CController.php:309   2604 runAction() /www/test.net/framework/web/filters/CFilterChain.php:134   2538 run() /www/test.net/framework/web/CController.php:292   2484 runActionWithFilters() /www/test.net/framework/web/CController.php:266   2251 run() /www/test.net/framework/web/CWebApplication.php:276   1799 translate() /www/test.net/application/libraries/Limesurvey_lang.php:118   1786 load_tables() /www/test.net/application/third_party/php-gettext/gettext.php:254   1447 runController() /www/test.net/framework/web/CWebApplication.php:135
参数解释:     sort:  对单词进行排序
     uniq -c:  显示唯一的行,并在每行行首加上本行在文件中出现的次数
     sort -k1,1nr:  按照第一个字段,数值排序,且为逆序
     head -10:  取前10行数据
3.3用strace跟踪进程
1)利用nohup将strace转为后台执行,直到attach上的php-fpm进程死掉为止:
nohup strace -T -p 13167 > 13167-strace.log &

参数说明:
-c 统计每一系统调用的所执行的时间,次数和出错的次数等.-d 输出strace关于标准错误的调试信息.-f 跟踪由fork调用所产生的子进程.-o filename,则所有进程的跟踪结果输出到相应的filename-F 尝试跟踪vfork调用.在-f时,vfork不被跟踪.-h 输出简要的帮助信息.-i 输出系统调用的入口指针.-q 禁止输出关于脱离的消息.-r 打印出相对时间关于,,每一个系统调用.-t 在输出中的每一行前加上时间信息.-tt 在输出中的每一行前加上时间信息,微秒级.-ttt 微秒级输出,以秒了表示时间.-T 显示每一调用所耗的时间.-v 输出所有的系统调用.一些调用关于环境变量,状态,输入输出等调用由于使用频繁,默认不输出.-V 输出strace的版本信息.-x 以十六进制形式输出非标准字符串-xx 所有字符串以十六进制形式输出.-a column设置返回值的输出位置.默认为40.-e execve 只记录 execve 这类系统调用-p 主进程号

2)也可以用利用-c参数让strace帮助汇总,非常方便非常强大![root@b28-12 log]# strace -cp 9907Process 9907 attached - interrupt to quitProcess 9907 detached% time     seconds  usecs/call     calls    errors syscall------ ----------- ----------- --------- --------- ----------------56.61    0.016612           5      3121           read11.11    0.003259           1      2517       715 stat  8.04    0.002358           7       349           brk  6.02    0.001767           1      1315           poll  4.28    0.001255           6       228           recvfrom  2.71    0.000796           1       671           open  2.54    0.000745           0      2453           fcntl  2.37    0.000696           1      1141           write  1.69    0.000497           1       593        13 access  1.37    0.000403           0      1816           lseek  0.89    0.000262           1       451        22 sendto  0.56    0.000163           1       276       208 lstat  0.49    0.000145           0       384           getcwd  0.31    0.000090           0      1222           fstat  0.28    0.000082           0       173           munmap  0.26    0.000077           0       174           mmap  0.24    0.000069           2        41           socket  0.23    0.000068           0       725           close  0.00    0.000000           0        13           rt_sigaction  0.00    0.000000           0        13           rt_sigprocmask  0.00    0.000000           0         1           rt_sigreturn  0.00    0.000000           0        78           setitimer  0.00    0.000000           0        26        26 connect  0.00    0.000000           0        15         2 accept  0.00    0.000000           0        39           recvmsg  0.00    0.000000           0        26           shutdown  0.00    0.000000           0        13           bind  0.00    0.000000           0        13           getsockname  0.00    0.000000           0        65           setsockopt  0.00    0.000000           0        13           getsockopt  0.00    0.000000           0         8           getdents  0.00    0.000000           0        26           chdir  0.00    0.000000           0         1           futex------ ----------- ----------- --------- --------- ----------------100.00    0.029344                 18000       986 total
ps:可以使用strace学习php解释器的解释执行过程
3.4加速PHP解释执行
如果自己的程序的确没有问题,只是执行了太多操作,没法再做优化了。则考虑使用APC或xcache等PHP加速器来减少CPU解释php文件的耗时。这些PHP加速器在php文件第一次解释时会生成中间代码opcode,所以之后的执行会快很多,并且减少了一些CPU的运算。下面以xcache为例,看下如何安装和配置。
安装xcache命令如下,./configure的参数好多不知道是做什么用的,官网上也没说明,所以只开启--enable-xcache了:     tar zxvf xcache-3.0.3.tar.gz     /usr/local/php/bin/phpize     ./configure --with-php-config=/usr/local/php/bin/php-config --enable-xcache     make     make install
php.ini中配置如下,最重要的是标红的两个参数,一般推荐xcache.size根据php文件多少来定,xcache.count与CPU核心数相同:
[xcache.admin]xcache.admin.enable_auth = Offxcache.admin.user = "xcache"xcache.admin.pass = ""
[xcache]xcache.shm_scheme ="mmap"xcache.size=1024Mxcache.count =16xcache.slots =8Kxcache.ttl=0xcache.gc_interval =0xcache.var_size=16Mxcache.var_count =1xcache.var_slots =8Kxcache.var_ttl=0xcache.var_maxttl=0xcache.var_gc_interval =300xcache.test =Offxcache.readonly_protection = Off;xcache.readonly_protection = Onxcache.mmap_path ="/dev/zero";xcache.mmap_path ="/tmp/xcache"xcache.coredump_directory =""xcache.cacher =Onxcache.stat=Onxcache.optimizer =Off
[xcache.coverager];;xcache.coverager =On;;xcache.coveragedump_directory =""

常见问题是启动php-fpm时会报错:     Cannot open or create file set by xcache.mmap_path, check the path permission or check xcache.size/var_size against system limitation这是因为/tmp/xcache是一个文件,而不能创建成目录。
重启php-fpm服务后,用top命令观察会发现每个worker进程的VIRT(包含了swap区)都是xcache.size大小,但REQ变得很小了。使用上面的配置在使CPU使用率的峰值时间变短了,但峰值时还是所有核心都会达到90%以上,不知道是不是哪里没有配置对。另外高并发时,/dev/zero这种配置方式经常会导致Nginx 502错误。/tmp/xcache和开启readonly_protection则很稳定。

4.php程序性能监控
常用的方法就是开启xdebug的性能监控功能,将xdebug输出结果通过WinCacheGrind软件分析。xdebug的安装和配合IDE调试的方法参见:Vim+XDebug调试PHP
php.ini中配置的这几项是输出性能信息的:
xdebug.auto_trace = on
xdebug.auto_profile = on
xdebug.collect_params = on
xdebug.collect_return = on
xdebug.profiler_enable = on
xdebug.trace_output_dir = "/tmp"
xdebug.profiler_output_dir ="/tmp"

这样XDebug会输出所有执行php函数的性能数据,但产生的文件也会比较大。可以关闭一些选项如collect_params、collect_return,来减少输出的数据量。或者关闭自动输出,通过在想要监控的函数首尾调用xdebug函数来监控指定的函数。
输出的文件名类似cachegrind.out.1277560600和trace.3495983249.txt,可以拿到Windows平台下用WinCacheGrind进行图形化分析。WinCacheGrind使用方法网上有很多介绍,这里就不详细说明了。Nginx+PHP-FPM优化技巧总结


结束语
以上都是近期做php程序优化工作总结出的一些优化方法,还请经验丰富的大牛们提出更好的建议,共同交流、进步~

参考资料
1)php-fpm优化方法汇总http://blog.haohtml.com/archives/11162
2)多Sock文件和php-fpm实例配置http://xn--ghqyhzj.com/post-21537.html

热点排行