Nginx + php-fpm - каждый php-fpm обрабатывает 70-100% ЦП при запуске

8

У меня есть ситуация, в которой происходит следующее:

  • Мы находимся на линоде с 8-ядерным, 8 ГБ оперативной памяти, 2,6 ГГц - используя nginx + php-fpm - мы получаем очень высокие графики использования процессора (которые мы не хотим быть такими плохими соседями VPS) ...

  • У нас на сайте одновременно меньше 100 пользователей - поэтому эта ситуация также невероятно смущает - что наш процессор очень высок.

  • Мы используем очень неизвестный, возможно, интенсивно работающий с php, сомнительно ужасный Framework вместо хорошо известных, хорошо документированных, хорошо продуманных других сред, таких как WordPress или Drupal, в которых есть много документации о кэшировании (а также плагины который обрабатывает кеширование) php на платформе nginx + php_fpm.

  • Таким образом, у нас есть около 6 открытых процессов php-fpm, которые при запуске запускают по отдельности БОЛЬШОЕ (30+ и часто около 99%) количество процессоров - и я не имею ни малейшего представления, как помешать им использовать столько процессоров , Я не могу сказать, какие php-скрипты вызывают эти всплески, потому что они происходят постоянно ... обычно работает только 1 или 2, но когда все 6 запускаются, мы максимизируем все 8 процессоров.

  • Мой файл pool.d / www.conf имеет следующие настройки:

    pm = dynamic
    pm.max_children = 10
    pm.start_servers = 4
    pm.min_spare_servers = 2
    pm.max_spare_servers = 6
    
  • Мы выполнили эту настройку, потому что, как я понимаю, наша память на самом деле потрясающая (htop показывает 472/7000 + мегабайт, без подкачки и т. Д.), И мы могли бы обрабатывать гораздо больше процессов и разбивать строку в ожидании получения обработанный - НО, к сожалению, поскольку каждый процесс слишком интенсивен на нашем процессоре во время работы - мы в конечном итоге загоняем наш процессор через крышу - поэтому мы не можем обрабатывать достаточное количество процессов.

  • Вопрос в том, что мы можем сделать, чтобы уменьшить использование процессора процессами php-fpm, чтобы мы могли увеличить настройки в этом конфигурационном файле пула для php-fpm, а также да, /var/log/php5-fpm.log кричит на нас, чтобы увеличить наших детей и настроить / увеличить наши минимальные / максимальные / стартовые серверы. Но это делает нашу нагрузку в среднем сумасшедшей, как говорилось ранее. Как мы можем сделать это без необходимости использовать кеш или каковы наши варианты?

  • Моя идея? Я читал кое-что об использовании cpulimit, чтобы гарантировать, что ни один процесс не займет больше, чем выделенное количество процессоров - но разве это замедлит процесс, чтобы его нельзя было использовать? Или, таким образом, мы могли бы увеличить нашу способность запускать больше, чем несколько процессов - я также подумал о запуске двух пулов - один для нашего сайта, ориентированного на будущее (на который обращаются клиенты), и другой для бэкенда (который влияет на наш сайт, ориентированный на будущее, когда время -отчетные отчеты запускаются).

  • Я потратил несколько дней на исследования, поиск в Google и т. Д. По этой теме - и это трудно, потому что ситуация каждого человека настолько уникальна для их системы - проблема в том, что такая специфическая неслыханная, возможно, плохо написанная - структура - делает трудно найти решение. Мы пока не можем просто отказаться от этой структуры - мне нужно найти какое-то решение.


ОБНОВЛЕНИЕ: я реализовал memcache для хранения php-сессий - потому что фреймворк в значительной степени зависит от пользовательских сессий, а природа нашей системы такова, что сотрудники часто используют несколько вкладок одновременно - каждая из них возвращается к сессиям для подтверждения способностей / пользовательских данных / и т. Д. ... так что я надеюсь увидеть некоторое увеличение производительности от этого - пожалуйста, прокомментируйте это, если хотите, - я посмотрю, как это будет завтра, когда мы преодолеем наши пиковые периоды увеличения объема.

amurrell
источник
Nginx не очень хорош для ресурсоемких веб-приложений - но наш высокий процессор плох - действительно плох - и мы работаем над его исправлением. Не нужно настраивать максимальное количество клиентов, потому что оно ДОЛЖНО быть способным поддерживать приличное количество клиентов - но высокая загрузка ЦП на процесс искажает эту возможность. Мы переключились на apache только потому, что он немного лучше при высокой загрузке процессора, но в конечном итоге эта проблема более показательна для проблемы веб-приложения, и для ее решения может потребоваться некоторое время, но сейчас нет времени, чтобы начать ее исправлять.
amurrell
Когда вы идете к врачу, и он говорит вам принять определенные лекарства - потому что он знает, что вы не будете слушать высказывания «перестаньте пить газировку и едите фастфуд» - именно поэтому для меня не было большого ответа - потому что правда На самом деле никаких настроек или быстрых исправлений - только грустная правда, что мы должны кардинально изменить само наше веб-приложение.
amurrell
К счастью, если у вас есть эта проблема с популярным фреймворком, у вас может быть возможность использовать кеширование и обильную документацию по этому поводу - но мы находимся в некоторых неясных случайных вещах, которые мы не можем изменить, кроме самого фреймворка. Ура!
amurrell
1
Итак, насколько я понимаю, opcache хранит ваш PHP-код в двоичном виде и может быть использован php-fpm гораздо быстрее (кэширование), но вы также должны использовать кеширование объектов. Например, хранение всей выходной страницы в виде объекта в чем-то вроде memcached. Это на самом деле кеширует вывод страницы (или другие вещи, которые вы хотите, например, сеансы php и т. Д.) ... Далее, вы также можете использовать лак, который является обратным прокси-сервером - но в основном это посредник между запросом и вашим сервером, так что ваш сервер не получает запросы напрямую - и он работает из памяти для обслуживания кэшированных URL-адресов.
Амуррелл
1
Varnish хорош для этого - хранит в памяти кэшированную копию того, что он получил с сервера, - поэтому лак берет на себя большую часть нагрузки. Мой нынешний работодатель работает на nginx, и мы используем лак и memcached. К счастью, у фреймворка, в котором мы сейчас находимся, есть собственный механизм кэширования для определения кэша страниц (выводимых данных страницы). На моей последней работе мне пришлось самому написать это в фреймворке - это было не весело, но сработало. Апач - я бы не стал переключаться обратно, если у вас нет времени, чтобы починить nginx ... Я ненавидел возвращаться, но это Единственное решение не полностью убить наш проект, пока я написал механизм кэширования.
Амуррелл

Ответы:

6

Несколько вещей для рассмотрения (заранее извиняюсь, если вы уже рассмотрели это): Прежде всего, убедитесь, что вы оптимизировали конфигурацию nginx и запускаете php-fpm только тогда, когда это абсолютно необходимо. Последнее, что вы хотите сделать, это позволить php обрабатывать такие вещи, как статические HTML-страницы (что он с удовольствием сделает).

Во-вторых, поскольку вы используете 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 секунд для реакции на сигналы от мастера.

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

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

Наконец, средство ограничения ресурсов процессора, о котором вы спрашивали, задокументировано здесь , но я бы прибегнул к нему, только если вы исчерпаете все остальные варианты. Если вы выберете этот путь, я определенно буду следить за возможным взаимодействием между настройками PHP-FPM и вашей конфигурацией limit.conf. В этот момент etckeeper может быть спасителем! :)

Удачи!

Rouben

Rouben
источник
Я собираюсь попробовать ограничить max_requests завтра - Кажется, что каждый процесс, который мы разрешаем, хочет съесть процессор, так что это может быть хорошей идеей. Мы используем пороги экстренного перезапуска, но мои цифры были немного выше - я попробую ваши и посмотрю, как идут дела. Спасибо за вашу тщательность - очень ценится. Хотите узнать ваши мысли о кешировании? Мне интересно, означает ли использование php-кэширования, что фреймворк должен быть адаптирован для этого. Я довольно новичок в этой концепции.
Амуррелл
3

Вы используете кеширование кода операции, верно?

Раньше это был APC, который использовался здесь, но это было довольно долго, и он был заменен Zend Opcache , который теперь является частью PHP с 5.5 и имеет обратный порт в PECL для 5.3 и 5.4.

Майкл Хэмптон
источник
Я заинтересован в этом Zend OpCache - мы находимся на 5.3 - Если бы вы могли расширить этот ответ, я был бы очень признателен!
Амуррелл
У нас был xcache - но теперь я выбрал Zend Opcache, установил его и подтвердил, что он работает и работает в phpinfo (). Я дам вам знать, если наша производительность лучше, в результате скрещивает пальцы
amurrell
Мне пришлось отключить zend opcache на данный момент - все работало, за исключением любого файла css или js, созданного динамическим php. Я пытался занести эти файлы в черный список из opcache - но либо черный список не работал, либо я не могу сказать, почему opcache заставляет nginx получить 502 ошибки шлюза ТОЛЬКО для этих файлов. Какие они мне нужны для шаблона, и они являются частью плохой основы. В логах nginx я получил тонны ошибок чтения - ошибка подключения 104-х узлов.
amurrell