幾臺(tái)使用了 nginx+php-fpm 的機(jī)器上,偶爾能看到php-fpm.log中有這樣的內(nèi)容
Oct 28 23:13:53.849419 [NOTICE] fpm_got_signal(), line 73: received SIGCHLD
Oct 28 23:13:53.849490 [WARNING] fpm_children_bury(), line 229: child 15044 (pool default) exited on signal 11 SIGSEGV after 1.332818 seconds
Oct 28 23:13:53.850341 [NOTICE] fpm_children_make(), line 305: child 15122 (pool default) started
如果得到SIGSEGV信號(hào)的進(jìn)程比較多的話,還能看到如下的日志
Oct 28 09:03:15.812009 [WARNING] fpm_children_bury(), line 256: failed PRocesses threshold (10 in 60 sec) is reached, initiating reload
Oct 28 09:03:15.812030 [NOTICE] fpm_pctl(), line 208: switching to 'reloading' state
然后php-fpm就會(huì)重啟。其中的
failed processes threshold (10 in 60 sec) is reached
是在php-fpm.conf中設(shè)置的,表示在60秒內(nèi)出現(xiàn)SIGSEGV或者SIGBUS錯(cuò)誤的php-cgi進(jìn)程數(shù)如果超過(guò)10個(gè),php-fpm就會(huì)重啟。可以通過(guò)把php-fpm.conf中的 emergency_restart_threshold的值設(shè)置的大一些來(lái)增加這個(gè)重啟的閥值,比如增加到60個(gè),在有些時(shí)候,這能夠避免php-fpm重啟,但這并不是解決問(wèn)題的根本辦法
SIGSEGV信號(hào)一般表示
SIGSEGV --- Segment Fault. The possible cases of your encountering this error are:
1.buffer overflow --- usually caused by a pointer reference out of range.
2.stack overflow --- please keep in mind that the default stack size is 8192K.
3.illegal file access --- file Operations are forbidden on our judge system
其中的第三條,跟本問(wèn)題的關(guān)系比較大。也就是php-cgi訪問(wèn)了一個(gè)不存在的或者沒(méi)有權(quán)限訪問(wèn)的文件
我用的php-fpm補(bǔ)丁是0.5.8版的,按照一些說(shuō)法,只要設(shè)置了
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
之后,php-cgi如果找不到文件或者沒(méi)有權(quán)限訪問(wèn)的話 會(huì)提示No input file specified. 或者Access denied.
問(wèn)題到這里似乎又陷入了僵局
后來(lái)又在php.ini中找到了php-cgi的一個(gè)參數(shù) cgi.fix_pathinfo
cgi.fix_pathinfo boolean
對(duì) CGI 提供了真正的 PATH_INFO/PATH_TRANSLATED 支持。以前 PHP 的行為是將 PATH_TRANSLATED 設(shè)為 SCRIPT_FILENAME,而不管 PATH_INFO 是什么。有關(guān) PATH_INFO 的更多信息見(jiàn) cgi 規(guī)格。將此值設(shè)為 1 將使 PHP CGI 修正其路徑以遵守規(guī)格。設(shè)為 0 將使 PHP 的行為和從前一樣。默認(rèn)為零。用戶應(yīng)該修正其腳本使用 SCRIPT_FILENAME 而不是 PATH_TRANSLATED。
把這個(gè)參數(shù)的值設(shè)置為1 ,cgi會(huì)多做一些檢查,來(lái)判斷請(qǐng)求的路徑中,那部分是文件名,哪部分是路徑名
下面是google groups上的一段話
when cgi.fix_pathinfo was set to "1" it caused a lot of checks in order to find which part of SCRIPT_FILENAME is a file name and which is PATH_INFO. In case of missing file it caused NULL
in path_translated, which caused the crash.
此問(wèn)題已經(jīng)耗費(fèi)了我太多的精力,已經(jīng)不愿意多花時(shí)間去查問(wèn)題了。比如,可以使用gbd來(lái)查看php-cgi 出錯(cuò)以后產(chǎn)生的dump文件。但這個(gè)問(wèn)題只是偶爾發(fā)生,很難捕捉到。如果有兄弟也遇到這個(gè)問(wèn)題,或者你有更好的解決辦法,不妨大家交流一下
修改此參數(shù)后,觀察了一段時(shí)間,SIGSEGV錯(cuò)誤在一些服務(wù)器上確實(shí)消失了。
新聞熱點(diǎn)
疑難解答