Пул PHP-FPM — чёрный ящик, пока не включить три вещи: журнал медленных запросов, страницу статуса и время ответа в журнале nginx. Включаются они за десять минут, а без них любая авария разбирается гаданием. Плюс одна грабля, из-за которой можно час смотреть не на те настройки.
Это четвёртая часть цикла «Сервер для WordPress».
1. Журнал медленных запросов
request_slowlog_timeout = 5s
slowlog = /proc/self/fd/2 ; в общий журнал контейнера
request_slowlog_trace_depth = 40
Любой запрос дольше 5 секунд оставит в журнале стек вызовов PHP: файл, строку, функцию. Это самая ценная улика при зависаниях — по ней авария из второй части была найдена с точностью до строки и адреса внешнего сервиса.
Вывод в /proc/self/fd/2 отправляет стеки в стандартный поток ошибок, а дальше — в journald вместе с остальным журналом контейнера. Отдельный файл внутри контейнера пропал бы при пересоздании.
2. Страница статуса пула
pm.status_path = /fpm-status.php
Сколько процессов занято, сколько свободно, длина очереди, сколько раз упёрлись в потолок max_children. Последний счётчик — главный: если он растёт, пул действительно мал.
Адрес статуса — с .php на конце. FPM выполняет только адреса с разрешёнными расширениями (security.limit_extensions), и запрос к /fpm-status он просто отвергнет. И, конечно, этот адрес не должен быть доступен снаружи: в nginx — только с локальных адресов.
3. Время ответа и статус кэша в журнале nginx
log_format timing '$remote_addr [$time_local] "$request" $status '
'rt=$request_time urt=$upstream_response_time cache=$upstream_cache_status';
$request_time — сколько ждал посетитель, $upstream_response_time — сколько из этого работал PHP, $upstream_cache_status — пришла страница из кэша или собиралась заново. С этими тремя полями жалоба «вчера долго грузилось» разбирается по журналу за минуту — подробно в 12-й части цикла про кэш страниц.
Грабля: проверка показывает не тот конфиг
Проверить итоговые настройки пула можно командой php-fpm -tt — она выводит все значения. В нашем образе она врёт:
# так образ запускает мастер-процесс
php-fpm -y /usr/local/etc/php-fpm/php-fpm.conf
# так проверка читает ДРУГОЙ конфиг (по умолчанию из пакета) — значения не те
php-fpm -tt
# правильно — тот же файл, что у работающего процесса
php-fpm -tt -y /usr/local/etc/php-fpm/php-fpm.conf
Без -y команда показывала значения конфига из пакета PHP, которых у работающего мастера не было. Можно долго «убеждаться», что таймаут стоит, глядя на чужой файл. Правило общее: проверять тем же путём, каким запускается процесс. Посмотреть его можно в ps -eo args | grep "php-fpm: master".
Минимальный набор
| Что | Зачем |
|---|---|
request_terminate_timeout | предохранитель от зависаний |
request_slowlog_timeout + slowlog | стек каждого медленного запроса |
pm.status_path | занятость пула и упоры в потолок |
$request_time, $upstream_response_time, $upstream_cache_status | кто ждал, сколько и почему |
Сайт иногда тормозит, а почему — непонятно?
Пришлите адрес — включу телеметрию пула и nginx и найду, где теряется время.
// загружаю комментарии…