php-fpm 與 Nginx優化總結(轉)

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


4338948-cf4e3a84aec9fc6d.png
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容