В журнале PHP-FPM появились предупреждения: «pool seems busy, spawning 8 children… 16… 32». Выглядит как перегрузка. Мы открыли журнал nginx за те же 15 секунд — и насчитали два запроса. А пул за это время вырос с 14 до 46 процессов.
Это тридцать первая часть цикла «Кэш страниц без MISS».
Откуда параллельность у последовательного обходчика
Обходчик ходит строго по одному адресу. Но при фоновом обновлении (вторая часть) устаревшая страница отдаётся мгновенно, а её рендер продолжается в фоне. Обходчик получает ответ за 20 миллисекунд и сразу шлёт следующий запрос — а предыдущий рендер ещё идёт. За обходчиком тянется хвост из десятка параллельных рендеров.
FPM видит, что свободных процессов нет, и начинает порождать новые, удваивая их число каждую секунду: 8, 16, 32. Это не нагрузка — FPM разгоняет себя сам.
| Где | Предупреждений |
|---|---|
| тестовая копия | 44 за 20 минут |
| рабочий сайт | 63–74 за 3 часа |
Посетители не страдали: потолок числа процессов не достигался, ошибок 5xx — ноль. Это шум в журнале и лишняя память на пиках.
Лечение из двух частей
1. Пауза — только после быстрого ответа
$t = microtime(true);
cache_request($path, $ua);
$ms = (microtime(true) - $t) * 1000;
if ($ms < 300) {
usleep(400000); // ответ был из кэша — дать фоновому рендеру закончиться
}
Безусловная пауза — грабля. После выката все ответы медленные (холодный рендер), и пауза после каждого растягивает круг. Замер: прогон успел 21 адрес из 942 вместо ~40, весь круг растянулся бы с 24 до 45 минут — ровно в то окно, когда холодная страница даёт посетителю MISS.
2. Тёплый запас пула
; отдельный файл, подключается после основного конфига пула
pm.start_servers = 16
pm.min_spare_servers = 4
pm.max_spare_servers = 20
Поднимать min_spare_servers — хуже. Интуитивно хочется держать больше свободных процессов. Но это порог, ниже которого FPM печатает предупреждение и начинает порождать. Поднятие с 4 до 12 дало больше предупреждений, а не меньше.
Результат
После обеих правок на рабочем сайте: 0 предупреждений за 11 минут против 22 за полчаса до правки.
И главный вывод: сначала разберитесь с частотой обхода, потом с пулом. На сайте с часовым добором было 493 таких предупреждения в сутки — там лечится не пул, а расписание (следующая часть).
В журнале PHP-FPM «seems busy», а трафика нет?
Пришлите журнал — разберу, кто на самом деле разгоняет пул.
// загружаю комментарии…