PHP-FPM/FastCGI + exit() вызывает всплески загрузки ЦП

У меня были периодические проблемы на некоторых серверах с Archlinux/php-fpm 5.3.9 в FastCGI на Cherokee 1.2.101. Я использую плагин кеширования, который создает и обслуживает статические файлы кеша, используя такую ​​логику:

$cache_file = md5($host . $uri) . '.cache';
if( file_exists($cache_file) ) {
  $cache_file_contents = file_get_contents($cache_file)
  exit( $cache_file_contents );
}
// else build/save the $cache_file

Несколько процессов окажутся в медленном журнале php-fpm, зависшего на этом вызове exit(). В это время происходит скачок нагрузки, 100% загрузки ЦП (почти) полностью передаются веб-серверу, а PHP-страницы начинают возвращать 500 — внутренние ошибки сервера. Иногда сервер восстанавливается сам по себе, иногда мне нужно перезапустить php-fpm и cherokee.

  • У меня есть настройки FastCGI для PHP-FPM, настроенные для выполнения

  • Несмотря на то, что это VPS, я бы предварительно исключил ожидание ввода-вывода в файловой системе, поскольку файл кеша уже должен быть загружен. Я не смог поймать его в действии, чтобы проверить с vmstat

  • У меня pm.max_requests установлено значение 500, но мне интересно, не мешает ли вызов exit() цикличности процессов.

  • Журнал php-fpm показывает много WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers). Кажется, это нормальная часть php-fpm, регулирующая количество дочерних процессов в пуле.

Буду признателен за любые советы по устранению неполадок. Вот 3 вещи, которые я обнаружил, которые вызвали некоторые опасения:

http://www.php.net/manual/en/function.exit.php#96930

https://serverfault.com/questions/84962/php-via-fastcgi-terminated-by-calling-exit#85008

Ошибки при вызове функции exit() для fastCGI?


person dalethedeveloper    schedule 15.02.2012    source источник
comment
Для устранения неполадок вы можете попробовать использовать strace, чтобы увидеть, что делает этот конкретный процесс: strace -p PID   -  person Marki555    schedule 22.02.2013


Ответы (2)


Это может быть связано с передачей вывода на сервер (также отслеживать ввод-вывод). Вы можете убрать FPM, заставив свой веб-сервер обслуживать статические файлы кеша. Кроме того, я бы посоветовал вам использовать этот фрагмент PHP вместо того, чтобы немного уменьшить объем памяти/ввода/вывода:

if (file_exists($cache_file))
{
    readfile($cache_file)
    exit;
}

См. readfile.

Если вы не хотите использовать exit (лично я никогда не сталкивался с проблемой его использования с FastCGI в PHP), вы следует очистить ваш код, чтобы не было необходимости использовать выход, например вы можете return или посмотреть в своем потоке кода, почему вам нужно использовать выход и устранить проблему.

person hakre    schedule 15.02.2012

В итоге я использовал метод упаковки исключений Pythonic, указанный в комментариях на http://www.php.net/manual/en/function.exit.php

В основном файле index.php

class SystemExit extends Exception {}

try{ 
    /* Resume loading web-app */
}
catch (SystemExit $e) {}

В логике кэша из вопроса, заменив exit( $cache_file_contents );

while (@ob_end_flush());
flush();
echo $cache_file_contents;
throw new SystemExit();

Это уменьшило медленные журналы php-fpm, которые показывают зависания на этом exit(). Я не совсем уверен, что это решило основную проблему, но оно очистило файлы журнала.

person dalethedeveloper    schedule 21.02.2012