Apache 2.4 Event MPM + php-fpm + php-opcache выдает ошибки «Сброс соединения узлом»

Apache 2.4 Event MPM + php-fpm + php-opcache выдает ошибки «Сброс соединения узлом»

У меня есть сервер CentOS 7, на котором запущен Apache 2.4.6 с Event MPM и php-fpm версии 5.6.10 (из репозитория REMI). Вот соответствующая конфигурация Apache для отправки запросов в php-fpm в пределах vhost (это единственный сайт на этом сервере):

<FilesMatch \.php$>
    SetHandler "proxy:unix:/var/run/php-fpm/www.sock|fcgi://localhost"
</FilesMatch>

Вот соответствующая конфигурация пула php-fpm:

listen = /var/run/php-fpm/www.sock
listen.owner = apache
listen.group = apache
pm = static
pm.max_children = 50
pm.max_requests = 0

Вот конфигурация php-opcache (конфигурация установки по умолчанию):

zend_extension=opcache.so
opcache.enable=1
opcache.memory_consumption=128
opcache.max_accelerated_files=4000
opcache.blacklist_filename=/etc/php.d/opcache*.blacklist

Моя проблема:Всякий раз, когда я устанавливаю и включаю php-opcache, в моем журнале ошибок начинают появляться следующие ошибки:

[Thu Jun 18 08:10:58.499871 2015] [mpm_event:debug] [pid 16546:tid 139798115227392] event.c(986): (104)Connection reset by peer: [client 157.55.39.233:15962] AH00470: network write failure in core output filter
[Thu Jun 18 08:10:58.527424 2015] [mpm_event:debug] [pid 16546:tid 139797922195200] event.c(986): (103)Software caused connection abort: [client 157.55.39.233:15990] AH00470: network write failure in core output filter

Если я удаляю php-opcache, ошибки прекращаются. Пользователи сообщают об ошибке 502 Service Unavailable на фронтенде всякий раз, когда это происходит.

Я буквально потратил не менее 6 часов, пытаясь гуглить и найти решения. Кто-то сказал, что fastshutdownпроблема в опции opcache, но она отключена в конфигурации по умолчанию. Я изменил метод управления процессами php-fpm на статический без рециркуляции (max_requests=0), но это тоже ничего не изменило. Я также попробовал использовать метод TCP-прокси с Apache (вместо сокетов), и это тоже не дало результата.

Я не уверен, относится ли это к делу или нет, но независимо от того, установлен ли php-opcache или нет, в журнале ошибок появляются следующие ошибки (но с гораздо меньшей частотой, <0,5% от всего трафика, что может быть отдельной проблемой):

[Thu Jun 18 08:32:37.223430 2015] [proxy_fcgi:error] [pid 19187:tid 140598765840128] [client 37.46.115.238:55624] AH01068: Got bogus version 10, referer: ...
[Thu Jun 18 08:32:37.223462 2015] [proxy_fcgi:error] [pid 19187:tid 140598765840128] (22)Invalid argument: [client 37.46.115.238:55624] AH01075: Error dispatching request to :, referer: ...

Эта проблема очень похожа наВот этот, хотя этот человек использует ProxyPassMatch с методом TCP, чего я не делаю (потому что он обходит .htaccess).

У кого-нибудь есть идеи, о которых я еще не упомянул?

решение1

Когда я видел подобные проблемы в наших средах, похоже, это было связано с тем, что OpCache (по умолчанию) разделяет один кэш между всеми пользователями в среде общего хостинга.ошибка была отправлена(и вы можете и должны пойти и проголосовать, чтобы дать знать разработчикам, насколько это может быть важно для вашего варианта использования), хотя никаких обязательств по предоставлению исправления не было.

TL;DR: По умолчанию, когда OpCache включен, кэш, который используется для хранения скомпилированного байт-кода, является общим для всех пользователей. В среде, где хостинг является общим для нескольких сайтов/пользователей,это может привести к тому, что сайт будет захватывать кэшированный вывод PHP-скриптов с другого сайта или, если включены определенные параметры безопасности, даже генерировать ошибки.

Если вы планируете использовать PHP-FPM со встроенным opcache PHP 5.5+, пожалуйста, прочтите сообщение в блоге ниже, прежде чем вы это сделаете. Оказывается, кэш opcode может быть прочитан любым пользователем на сервере. Это означает, что если есть, скажем, 10 отдельных пользователей со своими собственными vhosts и каталогами, и вы настраиваете один пул PHP-FPM на пользователя, каждый пользователь все равно может видеть, какие скрипты кэшируются и их местоположение. Поскольку у них есть доступ на чтение к кэшу, они потенциально могут просматривать все эти данные.

Очевидно, что это серьезная проблема безопасности, и даже если никто ею не воспользуется, все равно существует вероятность того, что скрипты будут прочитаны не тем пользователем при генерации страницы, поэтому веб-сайты могут отображать неверные данные/информацию, если в кэше находится несколько скриптов index.php.

Хотя официально исправление не было выпущено, если вы используете cPanel,в этой вики есть документированный способ настройки пулов php-fpm, которые создаются и защищаются для каждого пользователя отдельнои если вы будете следовать инструкциям ниже, а такжеВАЖНЫЕ ЗАМЕТКИв конце этого ответа вы сможете получить желаемую функциональность без каких-либо ошибок

В этом посте также описывается, как вы можете настроить это вручную для каждого сайта/пользователя (хотя я готов поспорить, что это может стать утомительным, если вы размещаете много сайтов). Если вы не используете cPanel, вам может потребоваться изменить скрипты, чтобы указать ваши индивидуальные пути и имена пользователей вместо переменных, используемых конфигурационным движком cPanel.


ВАЖНЫЕ ЗАМЕТКИ

В ходе тестирования и дополнительных исследований я столкнулся сэта статья, которая дает несколько разъясненийкоторые могут иметь отношение к вашей конкретной ситуации:

  1. Вам необходимо убедиться, что opcache.use_cwdпараметр установлен trueв соответствии с конфигурацией OpCache вашего приложения — он установлен falseпо умолчанию, и если оставить его установленным по умолчанию, то, скорее всего, возникнут конфликты, если в вашей системе размещено более одного PHP-приложения:

Прежде всего, вероятно, в каждом типичном проекте вам придется убедиться, что параметр opcache.use_cwd установлен в значение true. Включение этого параметра означает, что движок OpCache будет просматривать полные пути к файлам, чтобы различать файлы с одинаковыми именами. Установка его в значение false приведет к конфликтам между файлами с одинаковыми базовыми именами.

  1. Если вы запускаете приложение на базе Zend Framework или другого аналогичного фреймворка, использующего аннотации, вам ТАКЖЕ необходимо убедиться, что директивы opcache.load_commentsи opcache.save_commentsустановлены в значение true. Вам следует еще раз проверить это предложение в документации вашего приложения/фреймворка, поскольку большинство из них уже обновили свои документы, добавив конкретные инструкции по правильному использованию OpCache для своих систем:

Также есть настройка, которая важна в инструментах и ​​фреймворках, использующих аннотации. Если вы используете Doctrine, Zend Framework 2 или PHP Unit, не забудьте установить настройки opcache.load_comments и opcache.save_comments в значение true. В результате комментарии документации из ваших файлов также будут включены в предварительно скомпилированный код, сгенерированный OpCache. Эта настройка позволит вам работать с аннотациями без каких-либо сбоев.

Если ваш проект основан на определенном фреймворке или веб-приложении, всегда полезно проверить документацию на предмет любых рекомендаций относительно конфигурации OpCache.

ВАЖНЫЕ ЗАМЕТКИ


Надеюсь, это помогло. А если вы используете cPanel, оставьте комментарий, чтобы рассказать нам, как вы справились с этой частью конфигурации! См. также этот вопрос и связанные с ним комментарии.

Связанный контент