У меня есть сервер, работающий на 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
В /etc/nginx/nginx.conf
это здесь
В /etc/nginx/sites-available/www.example.com
это здесь
и перезапустил снова 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/