Все началось с апдейта php, давным давно и в этой же самой галактике. И с того момента меня преследовала одна мерзкая проблема, которая портила мне жизнь на протяжении достаточно длительного времени.
Я использую php лишь для нескольких сайтов: блог на wordpress, форум на phpbb и небольшой сайтик на modx. Сие работает в связке nginx + php-fpm. Apache я принципиально не использую, так как nginx умеет все. У каждого fpm своя учетка, своя home, все зарезано и перерезано, чтобы только работало радовало мою параною.
И вот после того самого древнего апдейта начались странности. При открытии одного из сайтов и последующем открытии другого сайта я получал ошибку от предыдущего.
То есть при открытии сайта на phpbb и следом сайта на modx я видел ошибку о неустановленном блоке от phpbb, при открытии сайта на modx и следом блога на wordpress я видел привет 503 от modx. Как будто каким-то странным образом один fpm поток получал доступ к скриптам с другого, работающего в другой директории, другом порте, другом юзере в другой группе…
С того момента утекло много воды, конфигурации nginx были переписаны несколько раз, fpm'ы менялись, использовал .sock вместо порта. Результат был один и тот же — при быстром открытии двух разных сайтов ответ был от пергого, а второй мне выдавай глюк движка первого сайта.
Если бы сайты были популярные, я бы подсуетился с поиском решения, но форум висел полумертвый, блог посещает несколько человек как и modx. И вот пару дней назад, будучи в рабочем настронии и наводя порядок на сервере нагуглил интересную статью How To Host Multiple Websites Securely With Nginx And Php-fpm On Ubuntu 14.04.
И именно эта цитата прояснила мне «who is ху..»:
Amazingly, if you run again the test steps in the exactly the same order, you'll be able to read the sensitive file regardless of its ownership and permission. This problem in opcache has been reported for a long time, but by the time of this article it has not been fixed yet.
Я сказал себе: «значит это opcache колбасит мои fpm'ы последние 7 месяцев, суя куда не попадя свой кеш и снося башню несччастным CMS'ам!»
Последовала небольшая правка
opcache.enable=0
и… проблема исчезла. Ее больше нет. Три несчастных сайта радостно рабоют, сервер мерно сопит в 384 дырки вентиляционного отверсия, а я чуть коснулся нирваны и даже прослушал пару треков.
Что я потерял с отключением opcache? opcache. Как это сказалось на моем перфомансе? Никак. Я использую кеш nginx, на сервере raid, а 8 ядер загружены в среднем на 5-10%. Так что лишний парсинг php скриптов ресурсов не съест. А визуально ничего не тормозит, в том числе и под нагрузочными тестами.
Частный случай? Может быть. Уже не багает? Вполне. Почему не php7? Потому, что. Апдейтить? Неа в топку, я на JSP код пишу.
Комментарии (63)
script88
26.06.2016 21:05+3Apache я принципиально не использую, так как nginx умеет все
Далеко не все. Даже и не знаю, что вам посоветовать, что бы развеять миф, который вы тут написали. Сравните список модулей хотябы.
Последовала небольшая правка opcache.enable=0
и… проблема исчезла. Ее больше нет. Три несчастных сайта радостно рабоют, сервер мерно сопит в 384 дырки вентиляционного отверсия, а я чуть коснулся нирваны и даже прослушал пару треков.
http://php.net/manual/ru/opcache.configuration.php#ini.opcache.use-cwdrockin
26.06.2016 21:19+4Ну, вообще-то я тоже за nginx обеими руками.
Когда вы пишете про «сравните список модулей», неплохо бы явно указать, что в apache есть такого, что нет в nginx.
А что есть и там, и тут, работает в apache быстрее, чем в nginx :D
Знаете, какое основное преимущество nginx перед apache для меня лично? Нормальная система организации конфигурационных файлов (когда всё в одном месте, а не размазано где-то там по .htaccess) — это очень удобно, когда получаешь чужой проект.script88
26.06.2016 21:59Допустим ldap auth. На gh есть реализация сторонего разработчика и использовать его, увы нельзя, т.к. во многих компаниях присутствует ограничения связанные с ИБ.
Nginx отличный продукт, но он не позиционирует себя как полная альтернатива apache2.
Знаете, какое основное преимущество nginx перед apache для меня лично? Нормальная система организации конфигурационных файлов (когда всё в одном месте, а не размазано где-то там по .htaccess) — это очень удобно, когда получаешь чужой проект.
.htaccess можно описывать в конфигах, просто основная масса разработчиков привыкла описывать все в .htaccess и многие делают это бездумно.nikitasius
26.06.2016 22:24-2Давайте не будет мешать все в одну кучу.
Я не указал, что именно умеет nginx, написав как «все», в то же самое время не указан и сектор применения. Но три php сайта, упомянутых в заметке — явно не корпоративный сектор, где и iis используют.
В плане конфигов и написания конфигов — nginx удобнее и сподручнее. В плане скорости работы — тут ему апач не ровень, по статике и по динамике.
http://php.net/manual/ru/opcache.configuration.php#ini.opcache.use-cwd
Спасибо ща линк, но я лучше оставлю opcache отключенным, ибо мне его функционал не нужен, у меня кеширование реализовано на стороне nginx.
Fesor
27.06.2016 00:56+7Допустим ldap auth
аж три варианта:
если есть деньги: https://www.nginx.com/blog/nginx-plus-authenticate-users/
если нет денег: https://github.com/kvspb/nginx-auth-ldap
если нет денег и не хочется что-то пересобирать — мидлвэр между приложением и nginx или же на уровне приложения.
Gendalph
27.06.2016 20:10+1Действительно, есть не всё и иногда приходится танцевать с бубном.
Но из-за обильности вариантов настройки Apache, он иногда ведет себя странно. И чем длиннее конфиг, тем чудесатее поведение Apache. Доходит до смешного — еженедельный рестарт Apache необходим, иначе через 2 недели он залипает.
Я не говорю что nginx абсолютно понятен и безглючен, но только при работе с Apache у нас в офисе выдается бубен.
romy4
28.06.2016 22:07В nginx нет AssignUserID, чтобы закрыть пользователя в его хомяке и не пускать к остальным, чтобы nginx писал под правами пользователя. Отключение htaccess в апаче кроме рутового существенно ускоряет его (хотя макросами можно подключить все необходиме htaccess). Ну и макросов в nginx очень нехватает. Приходится писать свой генератор конфига.
Fesor
29.06.2016 00:54+1чтобы nginx писал под правами пользователя
У меня nginx-у запрещено "писать".
nikitasius
29.06.2016 10:14чтобы закрыть пользователя в его хомяке и не пускать к остальным
При верно настроенном в конфиге root nginx не лазает по серверу в целом, а проблему «кто-то закинул символич. ссылку» решается просто отключением обработки этих самых ссылок в соотв. конфигах (популярнные CMS, к примеру).
чтобы nginx писал под правами пользователя.
У меня nginx писал только в случае с webdav, которая так же изолорована в конфигах (nginx).
Ну и макросов в nginx очень нехватает
Из «коробки» в конфигах nginx можно реализовывать простую логику на основе if и переменных, но очень простую. Для продвинутого варианта конфигов есть lua модуль. Правда я им никогда не пользовался, но его потенциал мне интересен. Если вы про логику конфигов…
bolk
26.06.2016 23:48+2Увы, нам на сервере разработки (там у каждого разработчика и у каждого релиза свой поддомен на одном php-fpm) опция use-cwd проблему не решила, решал проблему так же — отрубил opcache.
script88
27.06.2016 00:07Opcache не надо использовать в development окружении.
Если требуется полная изоляция, то надо юзать отдельный пулл fpm для проекта.nikitasius
28.06.2016 23:48+1Если требуется полная изоляция, то надо юзать отдельный пулл fpm для проекта.
Мне уже лень отвечать таким комментаторам. ctrl+F пулл на страничке.script88
29.06.2016 00:16Из топика я увидел только проблему и никакой конкретики, все только на словах. Я использую opcache на всех проектах крупных проектах под нагрузкой и проблем таких не было. Суть поста сводится к нулю, ибо вы проблему не решили, а обошли.
nikitasius
29.06.2016 00:47Я использую php во всех 3х мелких проектах, на плавающей нагрузке (между лещем и золотой рыбкой). Проблема… Сие безобразие прекрасно устраняется отключением opcache на моем сервере.
Честное слово, кучу говна лучше обойти, чем рыться в ней и докапываться почему ее тутнасралинакодили.
Исправили в другой 5.6? Исправили в 7? Какая разница. PHP мне вообще не важен, крутился бы блок и форум.Fesor
29.06.2016 00:55Зачем тогда статью писали? Крик души? Для этого есть твиттеры.
nikitasius
29.06.2016 10:01Ловите ответ в миске с каемкой: устранение перекрестных ошибок CMS работающих в разных fpm pool.
zenn
26.06.2016 21:14+3Странно, сколько пользуюсь такой же связкой с десятком сайтов ни разу не натыкался на такую «коллизию». Статья без логов подобной «ошибки» выглядит пустоватой (логи nginx / php-fpm могли бы пролить свет на эту ситуёвину или хотя-бы помогли понять на какой стадии запрос «умирал» и с каким стактрейсом).
nikitasius
26.06.2016 22:26-3А что вы хотите увидеть в логах?)
Там ничего интересного нет. Логи ошибок nginx — в них решения нет. Логи самого fpm — проблема уже решена.
youROCK
26.06.2016 21:28+3Хоть бы версию PHP сказали и опции php.ini, которые относятся к opcache
nikitasius
26.06.2016 22:27+15.6.18
youROCK
27.06.2016 01:05+1А настройки-то какие?
nikitasius
27.06.2016 09:28+1«Из коробки»:
04-suhosin.ini 05-opcache.ini 10-pdo.ini 20-curl.ini 20-gd.ini 20-imagick.ini 20-json.ini 20-mcrypt.ini 20-memcached.ini 20-memcache.ini 20-mysqli.ini 20-mysql.ini 20-pdo_mysql.ini 20-pdo_sqlite.ini 20-readline.ini 20-sqlite3.ini 20-xmlrpc.ini 20-xsl.ini
Вphp.ini
добавлены disable_functions, memory_limit и подкручены настройки smtp, safe mode выключен, а cgi.fix_pathinfo равен 0.
Данный ini как наследие с более древней версии, ноdiff -uraN
выдает немного правок в сравнении с PHP-5.6.18/php.ini-production.
koceg
26.06.2016 21:31У меня с opcache вот такая проблема уже давно висит: https://toster.ru/q/126933.
Проблема в том, что проект нагруженный и без него нагрузка на сервер вырастает очень сильно.
Fedcomp
26.06.2016 23:07+1Если php-fpm имел разный пул для каждого сайта, как они тогда пересекались? думаю в вашей конфигурации были не раздельные пулы.
nikitasius
27.06.2016 00:27+1Неверно думаете. Каждый из 3х сайтов висит на своем пуле в своей home под своей учеткой в своей группе на своем порте.
Fedcomp
28.06.2016 08:19на порте? зачем?
nikitasius
28.06.2016 09:21Как зачем?
Можно использовать как tcp сокеты, так и unix сокеты. Последние никто использовать не заставляет, да и нет надобности 20%-30% бусте для передачи ответа от динамики, хотя для параноика будет приятнее (права к файлам).
Но проблема была на обоих сокетах (и tcp и unix) и, как я писал это в статье, разрешилась отключением opcache.
kolu4iy
28.06.2016 11:06Точно не осталось примеров конфигурации с разными пулами? Дело в том что они действительно должны быть изолированы друг от друга. Про use-cwd вам уже писали. И кроме того, кеш nginx и opcache в php это сильно разные вещи все-таки. Вы проблему не нашли, вы её избежали путём сознательной просадки производительности.
nikitasius
28.06.2016 23:47+1Дело в том что они действительно должны быть изолированы друг от друга.
На разные сервера вынести?) Не удержался.
user/group, chroot и listen на своем порте.
И кроме того, кеш nginx и opcache в php это сильно разные вещи все-таки.
Конечная цель-то одна. Лишь пхп отдает свежий ответ от заранее скомпиленного скрипта, а nginx отдает заранее сохраненный ответ. Кеш nginx у меня сделан хитро, и бОльшая часть юзеров видит закешированный ответ на тех сайтах, и лишь некоторые имеют кеш по кукисам.
сознательной просадки производительности
Ничего не просело, все спрятано за nginx и сайты не рилтайм.Temmokan
29.06.2016 04:55Насколько я понял описание всего вашего Web-хозяйства, оно а) малонагруженное, и б) использует достаточно мощное железо. Просадка просто незаметна. Полагаю, что если бы вам нужно было обслуживать высоконагруженный сервер с сотнями килопосетителей в час, вы бы слегка иначе смотрели бы на Opcache и его альтернативы.
Вам конкретно он не нужен. Замечательно. Я сам предпочитаю статику и кэширование везде, где только возможно — существенно улучшает ситуацию в т.ч. с точки зрения информационной безопасности.
Когда и если вам потребуется поддержка чего-то жутко нагруженного и требовательного е ресурсам, да ещё и работающего на PHP, будет веский повод вернуться к нашим барашкам. :)nikitasius
29.06.2016 10:07+1обслуживать высоконагруженный сервер с сотнями килопосетителей в час
Самописные (JSP) легко держали около наплыв около 36000 уников за 24 часа (большей частью США, спасибо реддиту), больше проекты никогда собирали. Так что burst был хороший:-)
если вам потребуется поддержка чего-то жутко нагруженного и требовательного е ресурсам, да ещё и работающего на PHP
Надеюсь, что до такого PHP не дойдет :-)
А ежели и дойдет, то буду брать сервер, и специально фитить его для php, если хватит ресурсов, то и базу туда же воткну.Temmokan
29.06.2016 10:14"Она уверенно разыгрывала испанскую партию, ей не менее уверенно отвечали сицилианской защитой".
Это к тому, что странно сравнивать JSP и PHP в данном контексте. Таки совершенно разные комплекты грабель. Примерно как тёплое с мягким сравнивать.
В общем, пока у вас нет необходимости в «акселераторах», спорить решительно не о чем.nikitasius
29.06.2016 10:27Это к тому, что странно сравнивать JSP и PHP в данном контексте.
Потому, что каждый упорно делает аспект на том, что в «моем случае» или «если бы мои php», когда php это последнее,с чем я работаюдержу работающим на сервере и окромя 3х сайтов там нету ничего и не будет. JSP будет, скрипты на Java по крону — будут. А вот PHP не будет.
И отключение глючного на 5.6.18 opcache пришлось к месту, так как решило проблему. И даже, если проблему пофиксили в будущих версиях, я все равно не буду обновлять PHP (и всю гирлянду его зависимостей), а оставлю как есть, без opcache.Temmokan
29.06.2016 11:11> я все равно не буду обновлять PHP (и всю гирлянду его зависимостей), а оставлю как есть, без opcache
Сайты видны всем желающим в Интернете? Если да, то категоричное «не буду обновлять» таки может боком выйти. Уязвимости, знаете ли, это явления, с которыми лучше считаться.
Но это, естественно, ваше дело.nikitasius
29.06.2016 11:42Так просто почитайте как эксплотирются уязвимоости!
Про движки я молчу — там апдейты регулярные, но и потенциальные дырки закрыты (xmlrpc или комменты на WP).
А до багов PHP пытаются достучаться или через запросы к серверу, или локально (аплоад файла через баг в CMS).
Никто не мешает вам контролировать что ваш сервер может получать из мира сего придумав логику в конфигах nginx, вооружившись регулярками в том числе.Temmokan
29.06.2016 14:21-1Позвольте, мне-то зачем выговаривать? Я вроде бы категоричных заявлений не делаю.
nikitasius
29.06.2016 14:55-1Несогласие с вашим мнением = выговор?
Уязвимости, знаете ли, это явления, с которыми лучше считаться.
в купе с
то категоричное «не буду обновлять» таки может боком выйти
для PHP это из разряда "включи центр обновлений windows и думай, что получаешь наслаждение", аргументированное "но там же апдейты безопасности, security!", хотя на деле бОльшая часть апдейтов это частные случаи, которых можно избежать.
Пока для PHP есть (очень для старых) версий мелкие баги, которые эксплуатируются через строку запроса, я могу спать спокойно, так как я контролирую запросы к серверу.
Если же, вдруг, внезапно, забагала сама CMS (modx/phpbb/wp) и закачали левый файл, через который багнули мой fpm, то максимум, чем я рискую — это директория самого сайта. Учетки пула не могут лазить по серверу, у них не те права. У них свой chroot и они зарезаны дополнительным софтом. Сервер (система) всегда up to date.Temmokan
29.06.2016 14:58А передёргивать зачем, простите?
> для PHP это из разряда «включи центр обновлений windows и думай, что получаешь наслаждение»
Отнюдь нет. Это из разряда «читай про обновления всех используемых модулей PHP, и не забывай обновлять, если они тебя касаются». Слегка отличается от «не обновляю, и не буду».nikitasius
29.06.2016 15:11А передёргивать зачем, простите?
не благодарите
Это из разряда
В плане PHP мне хватает зайти 1 раз в день-два на хабр, если справа ничего нет, значит нет смысла суетится.
Ну и, наконец, перечитайте внимательно, какие о каких апдейтах идет речь. Или вы пытаетесь меня ловить на словах, вертя их так и так? Мол такой школьный челленж? Уж не танцевать ли в треде пытаетесь?
Я не кричу, просто громко печатаю, у меня пальцы сильные.Temmokan
29.06.2016 15:13> В плане PHP мне хватает зайти 1 раз в день-два на хабр, если справа ничего нет, значит нет смысла суетится.
Теперь вопросов не осталось, спасибо.
DexterHD
26.06.2016 23:20+3Неа в топку, я на JSP код пишу.
Java разработчик не справился с php? :D ROFLnikitasius
27.06.2016 00:29Java разработчик не справился с php? :D ROFL
С какой стати Java кодер должен разбираться с php? Разве нет более важных дел?)
Shannon
27.06.2016 05:01+2Я вот хоть не java-разработчик, но было что-то похожее на php 7.0, перепробовал множество настроек, это не помогло (оно и понятно, до этого работало, после апгрейда перестало)
Не знаю помогло бы мне, будь я java-разработчиком, но временно пришлось отключить opcache
В итоге спустя пару php сборок это исправили и включил обратноnikitasius
27.06.2016 09:41+1А сама логика opcache: кеширует результат компиляции php файла. По дефолту 2 секунды. Что позволяет выполнить 20 раз php файл за эти самые 2 секунды при 10 запросах в секунду без повторной перекомпилации.
Вроде бы круто. Но если на nginx у вас кеш от 1 до 10 секунд, а сайт не realtime, то я не вижу смысла (в моем случае) использовать opcache, чтобы быстрее отдавать, так как ответ сервера уже записан в кеш под тем или иным ключом (к примеру с учетом кукисов или нет).
Temmokan
27.06.2016 07:50+3Скорее запись в жалобную книгу, нежели информативная статья: «есть в PHP Opcache какой-то баг, проверять обновления я не стал, просто отключил Opcache». В статье, на которую ссылка, также нет упоминания записи в bugs.php.net, чтобы следить за статусом бага.
nikitasius
27.06.2016 09:33+2Так в статье есть ссылка, и даже приведена цитата, что ранее об этом сообщали. Какой смысл плодить новые тикеты?
Обновлять 5.6.18 на 7-ую версию я не буду, так как то, что требует php нормально себе работает на 5.6.18. И тут не хостинг компания, не хостинг сайтов клиентов, а 3 небольших сайта за мощной спиной nginx'а. Я бы рад от них избавится, но заменить нечем, хотя бы тот же wordpress.Temmokan
27.06.2016 09:52В статье (англоязычной) нет ссылки на баг в трекере PHP, только общая фраза «This problem in opcache has been reported for a long time, but by the time of this article it has not been fixed yet.»
Насколько понимаю, возможные обходные манёвры, вроде «opcache.use_cwd = 1» не проверялись?
JFYI, текущая версия ветки 5.6: 5.6.23.nikitasius
27.06.2016 10:32В статье (англоязычной) нет ссылки на баг в трекере PHP
Мне так же лень искать, как и им.
вроде «opcache.use_cwd = 1» не проверялись
Нет. После получения наводки на opcache и его отключения все встало на свои места. Немного погуглив про opcache я понял, что погоды он мне не сделает. Кеш nginx всем контентом заведует.
JFYI
Я уже не помню, зачем на 5.6.18 переходил. Вероятно из-за каких-то частных системных апдейтов поломался старый php, судя по датам конфигов это был апдейт libc.
kolu4iy
27.06.2016 10:25-1Э-э-э… А вы не пробовали разные сайты в разных пулах fpm крутить? Это же не просто так придумано…
P.S. По сравнению с APC мне opcache дал очень много стабильности. Просто надо правильно его готовить.
inoyakaigor
27.06.2016 15:45Вы очень вовремя с этой статьёй. Недавно переехал с Апача на NGINX + php-fpm и начал наблюдать на пуле клиентских сайтов с такую же проблему: один сайт работает, а какой-то другой валиться с 502-й. Точнее либо клиентские на Вордпрессе работают, либо мой самописный. Помогал перезапуск php-fpm. Надеюсь ваше решение поможет.
nikitasius
27.06.2016 15:46Напишите потом в комментарии помого или нет.
inoyakaigor
27.06.2016 15:48Постараюсь не забыть
inoyakaigor
30.06.2016 11:003 дня – полёт нормальный. Раньше за это время уже что-нибудь упало бы. Можно сказать, способ рабочий.
kolu4iy
29.06.2016 11:07+1Вот читаю я комментарии, и понимаю что приблизительно половина «администраторов» не пытается разобраться в проблеме. «У меня ошибка 502». При этом логирование ошибок PHP не настроено, логирование ошибок OPCACHE тоже отключено. Попыток разобраться нет, но есть попытки решить проблему методом инженерного тыка. Автор статьи предложил простейший вариант, без глубокого анализа ситуации и без дисклеймера о возможных последствиях данного решения, при этом выставляя «серебрянной пулей» кеш nginx. Я, кстати, тоже с глубоким уважением отношусь к nginx и использую его в боевых системах, однако серебрянной пули в ИТ просто нет. Для каждой проблемы существует свой интрумент и свой путь решения, скорее всего не один.
Например, у opcache кроме use-cwd есть много других интересных настроек. Например, если мы знаем, что проблема в конкретном файле — opcache.blacklist_filename. Если мы получаем ошибку «Cannot redeclare class», то надо использовать opcache.dups_fix=1.
Судя по всему, автор выбросил микроскоп, потому что им неудобно забивать гвозди.
Поскольку в статье дисклеймера нет, позвольте его добавить: «Коллеги, будьте добры, разбирайте каждую проблему до конца. Бросать разбор на полпути — это достойно только мальчика-энекейщика, который банально не смог дочитать документацию и/или логи ошибок. Не выбрасывайте микроскоп, как и любой другой инструмент. Лучше позовите на помощь более опытного коллегу, и он покажет вам способ поиска корня проблемы».nikitasius
29.06.2016 12:08-2Судя по всему, автор выбросил микроскоп, потому что им неудобно забивать гвозди
Просто автору нет дела до причин неработоспособности opcache в силу того, что php на сервере это как небольшаязанозатри занозы в заднице.
Автор статьи предложил простейший вариант, без глубокого анализа ситуации и без дисклеймера о возможных последствиях данного решения, при этом выставляя «серебрянной пулей» кеш nginx.
Кеш nginx это очень и очень мощный инструмент. По дефолту, из коробки, opcache компилит php 1 раз в 2 секунды. У меня кеш от 1 до 20 секунд на тех php сайтах. Причем не просто кеш, а кеш с fastcgi_cache_lock. Некоторая динамика вынесена на CF как API, что вообще снимает с меня нагрузку на 4 часа.
В итоге:
- Узнав, что это opcache косячит — починить его потратив на это свои человекочасы, правильно настроить, потратив на это бесполезное в данном случае занятие снова человеко часы, протестировать сие в течении пары дней, читая логи (как хорошие так и плохий). Написать что-нить о починке, про траляля. Не себе, а людям php программистам.
- Узнав, чтр это opcache косячит — отрубить его. Написать об этом рассказав nginx и дав php программистах свободу для действий в случае если они натолкнутся на этот же самый баг.
Я ейбогу не хочу тратить свое время на решение этой проблемы. Для меня opcache это не что-то сверх важное, что бустит перфоманс или определяет мой доход, а просто очередная примочка, от которой я могу свободно отказаться в силу:
- мощного железа
- кеша nginx
- кеша CDN
- низкой популярности 3х сайтов
p00h
Вот это да.
nikitasius
И я про тоже. Но после
opcache.enable=0
проблема исчезла. Я доволен как слон, завтра буду шкаф для ванной делать и бродивший виноградный сок пить.