Постоянно приходится перезагружать PHP-FPM

27

У нас довольно сильно загруженный сервер с nginx и PHP-FPM. У нас есть 6 веб-сайтов на этом сервере с PHP-FPM и nginx. Все программное обеспечение vBulletin 3.8 и WordPress. Базы данных находятся на отдельном сервере.

Теперь, потому что это очень популярные веб-сайты, у нас обычно 7-8 000 посетителей онлайн одновременно, причем каждая страница в основном попадает в базу данных. Я считаю, что это является причиной наших проблем.

Поскольку у нас так много больших баз данных на сервере MySQL, и, поскольку, честно говоря, запросы могли бы быть намного лучше в программном обеспечении, я думаю, что MySQL иногда не сможет своевременно возвращать результаты в PHP, создавая эффект каскада, который в конечном итоге заставляет все просто остановиться, пока мы не перезагрузим PHP-FPM. После того, как мы это сделаем, все снова начнет работать нормально.

Причина, по которой у меня возникают проблемы с устранением неполадок, заключается в том, что я ничего не могу различить по журналам. В журнале медленных запросов MySQL я не вижу ничего интересного в случае простоя. В журналах nginx я вижу тысячи записей о том, что истек срок ожидания запроса на чтение или тайм-аут подключения (к PHP-FPM). И в журналах PHP-FPM я вижу много строк, в которых говорится «время выполнения истекло (31 сек), завершение

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

Сейчас у меня просто есть crontab для обслуживания перезагрузки php5-fpm каждые 10 минут, который решает проблему сбоя. Конечно, когда PHP перезагружается, nginx выдает ошибку шлюза 502, так что это не очень большая часть решения.

PHP работает кеш APC, если это имеет значение. Я читал в нескольких местах, что APC может вызвать зависание при определенных обстоятельствах.

Любые указатели будут полезны. Мне бы очень хотелось, чтобы об этой машине не приходилось все время беспокоиться.

Более подробная информация может быть предоставлена, конечно. Просто дай мне знать, что тебе нужно.

Обновление: я просто скопировал файл apc.php в корневой веб-каталог и зашел к нему, чтобы посмотреть нашу статистику. Все выглядело хорошо. Затем я нажал на ссылку, чтобы перейти к статистике пользователя, и БУМ сервер мгновенно завис. Я перезагрузил php-fpm, а затем перезагрузил страницу статистики пользователя, и она прошла нормально. Подождал минуту, перезагрузился снова, сервер снова завис.

Так что это определенно связано с APC. Вопрос - как это исправить?

APC Config:

[apc]
apc.enabled="1"
apc.stat = "1"
apc.max_file_size = "2M"
apc.localcache = "1"
apc.localcache.size = "256"
apc.shm_segments = "1"
apc.ttl = "3600"
apc.user_ttl = "7200"
apc.gc_ttl = "3600"
apc.cache_by_default = "1"
apc.filters = ""
apc.write_lock = "1"
apc.num_files_hint= "10000"
apc.user_entries_hint="10000"
apc.shm_size = "1G"
apc.mmap_file_mask=/tmp/apc.XXXXXX
apc.include_once_override = "0"
apc.file_update_protection="2"
apc.canonicalize = "1"
apc.report_autofilter="0"
apc.stat_ctime="0"

Обновление 2: мы добились определенного прогресса в этом здесь. Оказывается, плагин кеширования WordPress (W3 Total Cache) - вот что вызывало сбои. Мы до сих пор не знаем, почему, но с его отключением мы работаем с PHP уже почти 4 часа без перезагрузок, замедлений и сбоев. Мы все еще используем APC на форумах vBulletin, и никаких проблем там нет. Есть ли способ определить, ПОЧЕМУ APC падает? Я хотел бы использовать его в наших установках WordPress, но не за счет хрупкой системы.

Kevin
источник
Можете ли вы опубликовать какие-либо настройки, связанные с APC?
Кайл
Да, хорошая идея Выполнено.
Кевин
Сколько оперативной памяти и своп у вас есть на этой машине? Сколько используется, когда оно начинает умирать?
Кайл
2
APC - ужасно глючный кошмар, и он был единственным источником таких сбоев на одном из моих веб-сайтов в течение многих лет . Я наконец полностью избавился от этого; и PHP сейчас твердый. Если вы хотите кэшировать, попробуйте Zend Opcache, который также является кэшем по умолчанию из PHP 5.5.
Майкл Хэмптон
1
Да, в конечном итоге это был APC, который разбивал PHP. Когда мы отключили APC, мы перестали постоянно перезапускать PHP.
Кевин

Ответы:

27

Вы используете php-fpm, поэтому я предлагаю быть более агрессивным в отношении того, как долго детям php-fpm разрешено жить. Вам нужно найти место между короткоживущими нитями / детьми и стабильностью. Значения по умолчанию для php-fpm - щедрый способ для любой производственной системы, ИМХО.

Я бы уменьшил число pm.max_requests для ваших производственных пулов. Я думаю, что по умолчанию 200. Я бы начал с 50 и посмотрел, куда это вас приведет.

В противном случае вы также можете попробовать эти глобальные параметры (AFAIK они все отключены по умолчанию):

emergency_restart_threshold=3
emergency_restart_interval=1m
process_control_timeout=5s

Что это значит? Если 3 дочерних процесса PHP-FPM завершаются с SIGSEGV или SIGBUS (то есть сбоем) в течение 1 минуты, то PHP-FPM должен перезапуститься автоматически. Дочерние процессы ждут 5 секунд реакции на сигналы от мастера.

Это должно поддерживать ваш пул рабочих потоков PHP красивым, свежим и чистым. Чем дольше работнику разрешено предоставлять запросы, тем более нестабильным он станет. Существует также более высокий риск утечки памяти.

Вот хороший обзор всех параметров конфигурации, которые я упомянул здесь, а также других: http://myjeeva.com/php-fpm-configuration-101.html

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

Rouben
источник
1
Каково ваше мнение о том, чтобы просто использовать cron для перезапуска php5-fpm каждый час?
CMCDragonkai
2
Это довольно грязный способ сделать это, и он может вообще не сработать. PHP-FPM имеет несколько встроенных настроек, поэтому лучше использовать эту возможность.
Рубен
1
Этот ответ указал мне правильное направление. Я сам видел аналогичную проблему, такую ​​как эта, решение для меня было изменить pmс dynamicна, ondemandи теперь все работает отлично со всеми другими значениями по умолчанию.
Иланато
(в php-fpm.conf) это должно быть «=» вместо «», разделяя ключ и значение. emergency_restart_threshold = 3 emergency_restart_interval = 1 м process_control_timeout = 5 с
Justyy
Я получаюERROR: [/etc/php/7.0/fpm/pool.d/www.conf:135] unknown entry 'emergency_restart_threshold'
deweydb