Nginx 上的 PHP5-FPM 崩潰 Zend/zend_language_scanner.c:沒有這樣的文件或目錄
我們目前的配置:
- Debian 8.6
- Nginx 網路伺服器
- PHP5-FPM v5.6.27-0+deb8u1
- Zend Engine v2.6.0 與 Zend OPcache v7.0.6-dev
我們使用Phalcon 框架 v2.0.11(和 v2.0.13 在測試環境中,我們遇到相同的錯誤)。為了工作,需要對 Phalcon 進行編譯,然後將其變為 PHP 預載入模組(phalcon.so)。在編譯期間,它會呼叫 Zend 庫等。
我們還使用Memcached(作為服務和 PHP 模組)。
應用程序執行正常,除了 Nginx 隨機拋出:
502 Bad Gateway
導航過程中的錯誤。重新載入頁面 (F5) 或按“返回”瀏覽器按鈕,頁面載入沒有任何錯誤。
有時,502 錯誤比其他時刻更頻繁,顯然與伺服器上的負載或流量無關。
我們可以從日誌中讀取的唯一錯誤根本不是雄辯的:
php5-fpm.log:
WARNING: [pool www] child 2183 exited on signal 7 (SIGBUS) after 0.120012 seconds from start WARNING: [pool www] child 1391 exited on signal 7 (SIGBUS) after 59.871442 seconds from start WARNING: [pool www] child 12836 exited on signal 7 (SIGBUS - core dumped) after 560.364868 seconds from start WARNING: [pool www] child 10874 exited on signal 7 (SIGBUS - core dumped) after 38.964131 seconds from start ... ...
nginx/error.log:
[error] 8428#0: *368771 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: xxx.xxx.xxx.xxx, server: xxxxxx.xxxxxxxxx.xxx, request: "POST /abc/def_ghi HTTP/1.1", upstream: "fastcgi://unix:/var/run/php5-fpm.sock:", host: "xxxxxx.xxxxxxxxx.xxx", referrer: "https://xxxxxx.xxxxxxxxx.xxx/abc" ... ...
經過幾天的研究,我們嘗試應用我們在網際網路上找到的所有建議。我們在 Nginx 和 php-fpm 上修改、測試和檢查的參數包括:
(on php.ini) output_buffering max_execution_time memory_limit (on www.conf) listen = /var/run/php5-fpm.sock or listen = 127.0.0.1:9000 pm = ondemand/static/etc..... pm.max_children 500/30/1/100/etc.... pm.start_servers = 30/50/1/etc...... pm.min_spare_servers pm.max_spare_servers pm.max_requests (on nginx virtual server conf file) fastcgi_pass fastcgi_buffers fastcgi_buffer_size fastcgi_connect_timeout fastcgi_send_timeout fastcgi_read_timeout
上述參數上具有任何值的每個組合都不會改變“502”錯誤行為的任何內容。它們有時會不斷出現。
因此,我們嘗試使用 GDB 在程序崩潰時轉儲 PHP 的核心。我們發現每次拋出 502 錯誤時,我們總是會收到相同的轉儲(我的意思是,有相同的錯誤)。這是轉儲的範例:
GNU gdb (Debian 7.7.1+dfsg-5) 7.7.1 Copyright (C) 2014 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from /usr/sbin/php5-fpm...Reading symbols from /usr/lib/debug/.build-id/d4/62618919aec6e5b126ad219b9d08046ef6b875.debug...done. done. [New LWP 17814] [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". Core was generated by `php-fpm: pool www '. Program terminated with signal SIGBUS, Bus error. #0 lex_scan (zendlval=zendlval@entry=0x7fff14a7b0b8) at Zend/zend_language_scanner.c:1082 1082 Zend/zend_language_scanner.c: no such file or directory.
錯誤是這個:
#0 lex_scan (zendlval=zendlval@entry=0x7fff14a7b0b8) at Zend/zend_language_scanner.c:1082 1082 Zend/zend_language_scanner.c: no such file or directory.
如果我們在網際網路上搜尋這個錯誤,我們發現很少或什麼也沒有。
我們嘗試在 PHP 升級(從 PHP 5.6.24 到 5.6.27)後重新編譯 Phalcon,但錯誤一直出現。
老實說,我們無法理解我們還應該做些什麼來解釋這個錯誤並理解如何明確地解決它。
感謝您的幫助。
問題解決了。它是由用於建構視圖的框架(Phalcon)中的一個組件(Volt 模板引擎)引起的。
經過我們進行的所有測試,我們發現問題與 Volt 相關,其中選項 compileAlways 設置為 true。
https://github.com/phalcon/cphalcon/issues/1949
https://github.com/phalcon/cphalcon/issues/11507
我們注意到配置 PHP-FPM 的選項 pm.max_children 大於 1(這意味著 PHP-FPM 可以同時滿足更多請求),“502”(Zend/zend_language_scanner.c 錯誤)正在驗證。但是,設置選項 pm.max_children = 1 (因此 PHP-FPM 一次最多服務 1 個請求)顯然會阻止 502 處理。
在網際網路上進行了更多研究後,我們發現了上面連結的兩個錯誤。並且使用 compileAlways=false 設置 Volt(使用 pm.max_children > 1)實際上解決了這個問題。
所以看起來 Volt 無法在並發請求上編譯相同的模板。
在生產環境中保持 compileAlways 為真當然是一個粗心的錯誤。該選項現在是錯誤的,一切正常。