PHP5-FPM при сбое Nginx 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". Они продолжают появляться иногда.
Итак, мы попытались сбросить ядро PHP при сбое процесса с помощью GDB. Мы обнаружили, что каждый раз, когда выдается ошибка 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.
Если мы ищем эту ошибку в Интернете, мы находим мало или ничего.
Мы попытались перекомпилировать Phalcon после обновления PHP (с PHP 5.6.24 до 5.6.27), но ошибка продолжает появляться.
Мы, честно говоря, не можем понять, что еще мы должны сделать, чтобы получить объяснение этой ошибки и понять, как ее решить окончательно.
Спасибо за помощь.
1 ответ
Проблема была решена. Это было вызвано компонентом в каркасе (Phalcon) для построения представлений (Volt Template Engine).
После всех проведенных нами испытаний мы обнаружили, что проблема связана с 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 работать очень быстро.
После еще одного исследования в Интернете, мы обнаружили две ошибки, связанные выше. И установка Volt с compileAlways=false (с pm.max_children > 1) фактически решила проблему.
Поэтому кажется, что Volt не может скомпилировать один и тот же шаблон при одновременных запросах.
Сохранение компиляции всегда верным в производственной среде было, конечно, ошибкой по невнимательности. Теперь опция ложная, и все работает хорошо.