Хостинг

Сайт отвечает 504, хотя ничего не менялось: как один медленный запрос кладёт соседние сайты

Эдгар Косулин 3 мин чтения

Содержание

В воскресенье 1 ноября в 9:57 по Москве сайт siteko.net начал отдавать 504. Вместе с ним ошибку получили блог, бот и страница, которую опрашивает наш мониторинг. За следующие 21 минуту в журнале нашлась причина: один адрес прислал 1052 запроса к проверке домена.

Это был краулер. Он прошёл по ссылкам на страницу цен и отправил проверку для каждого имени подряд. Проверка домена ходит к реестру и ждёт его ответ. В среднем это около 6 секунд, отдельные проверки шли дольше. Всё это время процесс PHP занят и ничего другого не делает.

Для обычного трафика 50 запросов в минуту немного. Но если каждый запрос держит процесс 6 секунд, этого хватает, чтобы занять почти весь пул. Посчитаем: 50 запросов по 6 секунд дают 300 секунд работы в минуту, то есть почти все процессы пула без перерыва. Остальные запросы встают в очередь.

Почему 504 получили все сайты

Пул PHP-процессов у нас общий: сайт, блог, бот и мониторинг стоят в одной очереди. Когда процессы заняты проверками, запросы остальных сайтов ждут там же. Nginx ждёт ответа отведённое время и отдаёт 504. Выглядит это так, будто упал весь сайт, хотя медленной была одна страница.

Почему сервер работал и на ушедшего посетителя

Посетитель, который не дождался, закрывает страницу. Для nginx это код 499: клиент ушёл раньше ответа. Но запрос уже стоит в очереди, и когда до него доходит черёд, PHP выполняет его целиком. Скрипт узнаёт, что ответ никому не нужен, только когда пытается его отправить.

Краулер тоже не стал ждать ответов, но его проверки всё равно выполнялись, и каждая держала процесс. Поэтому медленный сценарий обходится дорого не числом посетителей, а тем, сколько времени он занимает процесс.

Что мы поставили на вход

Ошибка была наша. Проверку домена мы сделали синхронной: страница ждёт ответ реестра прямо в обычном запросе, без лимита и на общем пуле. Пока реестры отвечали быстро, это никому не мешало. Теперь стоят четыре вещи:

  • Лимит частоты на проверку домена с одного адреса. Лишние запросы получают 429 на уровне nginx, ещё до PHP. Короткий всплеск пропускается, так что человек, который нажал пару раз, не упирается в стену.
  • Больше рабочих процессов в пуле. Это запас, а не решение: тот же поток запросов теперь занимает меньше половины процессов.
  • Короткие таймауты. Соединение с реестром ждём не дольше 3 секунд, весь ответ не дольше 10. Раньше на соединение уходили те же 10 секунд, что и на весь ответ. Регистратору отводим 5 и 15 секунд.
  • Прокси для реестров. Часть реестров с нашего сервера не отвечала: TLS зависал, и каждая проверка ждала до конца таймаута. Такие запросы теперь идут через отдельный прокси.

Почему лимит не решает задачу до конца

Лимит считается по адресу. Краулер с сотней адресов его обойдёт, поэтому лимит защищает от одного настойчивого источника, но не от массового обхода. Надёжнее не ждать внешний сервис внутри запроса: проверку можно выполнять в фоне, а страница покажет результат, когда он будет готов. Мы до этого пока не дошли. Проверка домена по-прежнему идёт в запросе страницы, поэтому лимит и таймауты остаются нашей защитой.

Что проверить, если ваш сайт отвечает 504

Начните с журнала доступа. Одна строка, которая повторяется сотни раз, чаще всего и есть ответ: медленная страница, поиск или бот. Журналы лежат в аккаунте, их можно читать через файловый менеджер панели или по SSH.

Потом ответьте на три вопроса. Открывает ли страница внешний сервис при каждом просмотре: оплату, доставку, курсы или проверку? Совпадает ли 504 по времени с cron или резервным копированием? Идёт ли по сайту волна одинаковых запросов с одного адреса?

Если ответов нет, напишите в поддержку время и адрес страницы. Мы сверим их с LVE-статистикой аккаунта и скажем, упёрся ли он в лимит и какой именно ресурс.

Как это устроено на Siteko. Каждый тарифный аккаунт работает в своих лимитах CloudLinux (LVE), поэтому перегруженный сайт обычно страдает сам, а соседние аккаунты нет. Статистику LVE смотрит поддержка, а журналы доступа вы читаете сами.

Как искать медленное место в сайте по слоям, разобрано в статье Сайт тормозит на хостинге: виноват тариф, код, база или внешний сервис. Настройку самого пула PHP-FPM мы разбирали в статье Тормозит сайт? Виноват не хостинг: тюним nginx и PHP-FPM. Проверку домена, которая попала в эту историю, описали в статье Свободен ли домен: как проверить самому.

PHP nginx

Поделиться: Telegram ВКонтакте

Новые статьи и разборы — в канале Siteko: Telegram MAX

Подписчикам: +30 дней к пробному хостингу, клиентам: +150 ₽ на баланс

Пошаговые инструкции по нашим услугам — в базе знаний

Ещё по теме

Почему с хостинга не уходят коды и письма с форм, что значит ошибка Sender rate overlimit и как посчитать, сколько писем нужно входу по коду.

«Хостинг без магии», часть 15

Хостинг 5 мин чтения

PHP2Shell: как мы закрывали уязвимость PHP на хостинге

Две критические уязвимости PHP, CVE-2026-109618 и CVE-2026-109619: какие версии затронуты, как закрыть дыру на хостинге и VDS и почему phpinfo может показывать старую версию.

Хостинг 9 мин чтения

Корпоративная почта: где её держать и сколько ящиков нужно на самом деле

Где держать корпоративную почту (на хостинге вместе с сайтом или в почтовом сервисе), сколько ящиков нужно на самом деле, кому принадлежат ящики сотрудников и при чём тут новый закон о цифровых почтовых ящиках.

«Почта на своём домене», часть 2