Назад | Перейти на главную страницу

Nginx + PHP-FPM Тайм-ауты, почти нулевое потребление нагрузки?

У меня есть сервер, работающий на Linode с Ubuntu 10.04 LTS, Nginx 0.7.65, MySQL 5.1.41 и PHP 5.3.2 с PHP-FPM.

На нем есть блог WordPress, недавно обновленный до WordPress 3.2.1.

Я не делал никаких изменений на сервере (кроме обновления WordPress), и, хотя он работал нормально, пару дней назад у меня начались простои.

Я попытался решить проблему и, проверив error_log, увидел много тайм-аутов и сообщений, которые, казалось, были связаны с тайм-аутами. Сервер в настоящее время регистрирует такие ошибки:

2011/07/14 10:37:35 [warn] 2539#0: *104 an upstream response is buffered to a temporary file /var/lib/nginx/fastcgi/2/00/0000000002 while reading upstream, client: 217.12.16.51, server: www.example.com, request: "GET /page/2/ HTTP/1.0", upstream: "fastcgi://127.0.0.1:9000", host: "www.example.com", referrer: "http://www.example.com/"

2011/07/14 10:40:24 [error] 2539#0: *231 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 46.24.245.181, server: www.example.com, request: "GET / HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "www.example.com", referrer: "http://www.google.es/search?sourceid=chrome&ie=UTF-8&q=example"

и даже видел это предыдущее обсуждение сбоя сервера с возможным решением: отредактировать /etc/php/etc/php-fpm.conf и изменить

request_terminate_timeout=30s

вместо того

;request_terminate_timeout= 0

Сервер проработал несколько часов, а потом снова сломался. Я снова отредактировал файл, чтобы оставить его как есть, и снова перезапустил php-fpm (service php-fpm restart), но не повезло: сервер работал несколько минут и снова и снова возвращался к проблеме. Странно то, что хотя службы работают, htop показывает, что загрузка процессора отсутствует (см. Изображение), и я действительно не знаю, как решить эту проблему.

Файлы конфигурации находятся на pastebin

В php-fpm.conf файл здесь

В /etc/nginx/nginx.conf это здесь

В /etc/nginx/sites-available/www.example.com это здесь

и перезапустил снова php-fpm [...] сервер работал несколько минут и снова и снова возвращался к проблеме

Проблема в конфигурации php-fpm

Но это не тайм-аут. Увеличение тайм-аута дает php больше времени для обработки одного запроса, что может маскировать симптомы, но не является правильным решением.

В журнале php-fpm должна быть очевидна причина проблем с сервером; по моему опыту (очевидно, из-за отсутствия информации это предположение) файл журнала php-fpm будет содержать такие записи:

#/var/log/php5-fpm.log
[19-Oct-2014 06:25:10] NOTICE: error log file re-opened
[19-Oct-2014 17:46:56] WARNING: [pool www] seems busy (you may need to increase
pm.start_servers, or pm.min/max_spare_servers), spawning 1 children, there are 
1 idle, and 5 total children
...

Если таких записей в журнале всего несколько, это не проблема. Если между ними много и всего несколько минут или секунд - значит, у php-fpm недостаточно ресурсов для нагрузки, с которой его просят справиться.

Это не редкость, потому что стандартный файл конфигурации dist php-fpm будет содержать что-то похожее на это:

# /etc/php5/fpm/pool.d/www.conf
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3

Это означает, что php-fpm будет обрабатывать не более 5 запросов параллельно.

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

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

Как это исправить

Если проблема в том, что у php-fpm слишком мало запущенных серверных процессов - просто увеличьте их. Используемые числа зависят от оборудования сервера, на котором оно развернуто; вот предложение:

# /etc/php5/fpm/pool.d/www.conf
pm = dynamic
pm.max_children = 20
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 15

Это позволит обслуживать 20 запросов параллельно - и должно облегчить любые проблемы, не вызывая проблем у сервера.

Если сомневаетесь, при изменении конфигурации php-fpm нужно следовать простому правилу:

  • Увеличивайте, пока сообщения об ошибках не исчезнут (и производительность будет приемлемой)
  • Уменьшите, если серверу не хватает памяти или загрузка сервера недопустима :)

Вы пробовали вместо "upstream" -ing в nginx.conf делать что-то вроде:

# Pass PHP scripts to PHP-FPM
location ~* \.php$ {
   try_files       $uri /index.php;
   fastcgi_index   index.php;
   fastcgi_pass    127.0.0.1:9000;
   include         fastcgi_params;
   fastcgi_param   SCRIPT_FILENAME    $document_root$fastcgi_script_name;
   fastcgi_param   SCRIPT_NAME        $fastcgi_script_name;
}

Взгляните сюда http://www.if-not-true-then-false.com/2011/nginx-and-php-fpm-configuration-and-optimizing-tips-and-tricks/