原創】Nginx+PHP-FPM優化技巧總結


【原創】Nginx+PHP-FPM優化技巧總結


分類: Nginx PHP  12033人閱讀 評論(0) 收藏 舉報

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     %idle

all     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.00

10     89.11      0.00      2.97      0.00      0.00      7.92

11     82.35      0.00      3.92      0.00      0.00     13.73

12     73.27      0.00      7.92      0.00      0.00     18.81

13     81.44      0.00      4.12      0.00      0.00     14.43

14     77.23      0.00      6.93      0.00      0.00     15.84

15     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 9907

Process 9907 attached - interrupt to quit

Process 9907 detached

% time     seconds  usecs/call     calls    errors syscall

------ ----------- ----------- --------- --------- ----------------

56.61    0.016612           5      3121           read

11.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 = Off

xcache.admin.user = "xcache"

xcache.admin.pass = ""


[xcache]

xcache.shm_scheme ="mmap"

xcache.size=1024M

xcache.count =16

xcache.slots =8K

xcache.ttl=0

xcache.gc_interval =0

xcache.var_size=16M

xcache.var_count =1

xcache.var_slots =8K

xcache.var_ttl=0

xcache.var_maxttl=0

xcache.var_gc_interval =300

xcache.test =Off

xcache.readonly_protection = Off

;xcache.readonly_protection = On

xcache.mmap_path ="/dev/zero"

;xcache.mmap_path ="/tmp/xcache"

xcache.coredump_directory =""

xcache.cacher =On

xcache.stat=On

xcache.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使用方法網上有很多介紹,這裏就不詳細說明了。





結束語


以上都是近期做php程序優化工作總結出的一些優化方法,還請經驗豐富的大牛們提出更好的建議,共同交流、進步~




參考資料


1)php-fpm優化方法彙總

http://blog.haohtml.com/archives/11162


2)多Sock文件和php-fpm實例配置

http://xn--ghqyhzj.com/post-21537.html


文件/usr/local/nginx/logs/error.log

FastCGI sent in stderr: "Access to the script '/var/www/html//phpmyadmin/setup/styles.css' has been denied (see security.limit_extensions)"

打開日誌發現會出現security.limit_extensions 這樣的錯誤。

經過查找資料發現 從5.3.9開始,php官方加入了一個配置"security.limit_extensions",默認狀態下只允許執行擴展名爲".php"的文件,造成了其他類型的文件不支持的問題。

所以更改策略如下:

修改/usr/local/php/etc/php-fpm.conf,找到security.limit_extensions把他修改爲:

security.limit_extensions=.php .html .js .css .jpg .jpeg .gif .png .htm#(常用的文件擴展名)

然後問題就解決啦!


來源: <http://www.tuicool.com/articles/euaY3m>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章