Сайт отвечает 502 или 504, в панели мониторинга красным горит «сервер недоступен», в чате уже пишут менеджеры — а в логах на первый взгляд ничего не понятно: тысячи строк, десяток процессов php-fpm, MySQL показывает какую-то активность. Именно в эти первые пять минут решается, займёт разбор десять минут или два часа простоя магазина.
Ниже — практический маршрут диагностики 502/504 и высокого CPU на BitrixVM: куда смотреть в первую очередь, как отличить исчерпание пула php-fpm от медленного SQL-запроса и от зациклившегося агента 1С-Битрикс, и что делать немедленно, а что — уже после того, как сайт снова открывается. Материал написан по нашей практике диагностики ошибок 502/504 и высокого CPU на BitrixVM — без общих слов про «проверьте логи».
Коротко
- 502 — php-fpm ответил некорректно или упал; 504 — php-fpm вообще не успел ответить за отведённое время.
- Диагностику начинайте с трёх источников:
error.lognginx, статус пула и slow log php-fpm, slow query log MySQL. - Три типичных виновника — исчерпанный пул php-fpm, медленный SQL-запрос без индекса и зациклившийся агент Битрикс — различаются по характерным признакам в логах.
- Немедленная митигация (перезапуск воркеров, снятие зависшего запроса) — не решение, а способ выиграть время до устранения первопричины.
- Грамотный мониторинг ловит проблему за 15–40 минут до полного падения сайта, а не постфактум по жалобам покупателей.
Симптом: сайт лёг, а причина не очевидна
502 Bad Gateway и 504 Gateway Timeout — это ошибки не самого 1С-Битрикс, а веб-сервера (в подавляющем большинстве конфигураций BitrixVM — nginx), который работает перед php-fpm как обратный прокси. Nginx принимает запрос от браузера и передаёт его дальше, в пул процессов php-fpm, которые уже выполняют код Битрикса. Обе ошибки говорят об одном и том же на уровне идеи: связка «nginx → php-fpm» не смогла корректно завершить запрос, но по разным причинам.
502 — nginx получил от php-fpm ответ, но некорректный или пустой: воркер упал (сегфолт, превышение memory_limit, убит OOM killer), соединение с апстримом оборвалось раньше срока. 504 — php-fpm вообще не ответил за отведённое время: запрос выполняется дольше, чем позволяет таймаут nginx (fastcgi_read_timeout), то есть процесс жив, но безнадёжно тормозит. Это разделение — первая и самая важная развилка диагностики: 502 указывает на «что-то упало», 504 — на «что-то не успевает».
Три лога, с которых начинается любая диагностика
На BitrixVM инцидент почти всегда виден на пересечении трёх источников. Каждый закрывает свою зону ответственности в цепочке запроса, и вместе они дают полную картину.
nginx error.log: как читать 502 и 504
Первым делом открывайте error.log nginx (типовой путь на BitrixVM — /var/log/nginx/error.log или журнал конкретного виртуального хоста в bx/scripts окружении). Ищите записи в момент инцидента с характерными фразами:
- «upstream timed out» — php-fpm не ответил за
fastcgi_read_timeout. Это прямой признак 504: запрос выполнялся слишком долго. - «no live upstreams» — вообще нет доступных воркеров php-fpm, пул полностью исчерпан или сервис php-fpm упал целиком.
- «recv() failed» / «premature end of script headers» — воркер php-fpm оборвал соединение раньше времени, часто из-за превышения
memory_limitили убийства процесса по нехватке памяти (OOM killer).
Важная деталь: в error.log видна не причина, а симптом на уровне транспорта. Дальше нужно идти в сторону php-fpm — смотреть, что происходило с пулом воркеров в тот же момент времени по временным меткам.
php-fpm: статус пула и slow log
У php-fpm есть встроенная страница статуса пула (включается директивой pm.status_path в конфиге пула, обычно доступна как /status?full). Она показывает в реальном времени:
| Поле статуса | Что означает | Тревожный признак |
|---|---|---|
| active processes | Сколько воркеров сейчас заняты обработкой запроса | Равно pm.max_children — пул исчерпан |
| listen queue | Сколько запросов ждёт свободного воркера | Больше нуля и растёт — явное исчерпание пула |
| max children reached | Сколько раз с момента запуска пул упирался в лимит | Значение растёт во время инцидента |
| slow requests | Число запросов, превысивших request_slowlog_timeout | Резкий рост — есть конкретные медленные запросы |
Ещё один незаменимый источник — slow log php-fpm (включается парой директив request_slowlog_timeout и slowlog в конфиге пула). В отличие от статуса, который показывает картину «сейчас», slow log пишет полную PHP-трассировку (backtrace) каждого запроса, превысившего порог по времени выполнения — то есть прямо называет файл, функцию и строку кода, на которой запрос завис. Это часто самый быстрый способ найти конкретный виновника без гадания.
MySQL slow query log и SHOW PROCESSLIST
Если php-fpm жив и воркеры не исчерпаны, а сайт всё равно тормозит или отвечает 504 — вероятная причина на уровне базы данных. Включённый slow query log (параметры slow_query_log и long_query_time, для инцидентов имеет смысл временно опустить порог до 0,5–1 секунды) покажет конкретные SQL-запросы, которые выполняются дольше нормы, вместе с числом просмотренных строк — часто именно тут видно отсутствующий индекс или запрос, который сканирует таблицу целиком.
Для картины «прямо сейчас» полезнее команда SHOW PROCESSLIST (или SHOW FULL PROCESSLIST) — она показывает все активные соединения и запросы в моменте, включая их состояние (Sending data, Locked, Copying to tmp table). Если один и тот же запрос висит в статусе Locked минутами — это уже не медленный запрос, а блокировка (например, долгая транзакция обмена с 1С держит блокировку на таблице, а десятки других запросов ждут своей очереди). Для более глубокой картины по блокировкам InnoDB используется SHOW ENGINE INNODB STATUS.
Три типичных сценария — сравнение
На практике подавляющее большинство инцидентов 502/504 на BitrixVM сводится к одному из трёх сценариев. Различать их удобно по набору характерных признаков:
| Признак | Пул php-fpm исчерпан | Медленный SQL-запрос | Зациклившийся агент |
|---|---|---|---|
| Статус пула | active = max_children, очередь растёт | Воркеры заняты, но не на пределе | Один-два воркера висят подолгу |
| MySQL | Обычно в норме | Запрос в slow log, много просмотренных строк | Может быть в норме или тоже нагружен |
| CPU сервера | Растёт пропорционально трафику | Скачок на одном ядре от MySQL-процесса | Скачок от одного PHP-процесса |
| Типичный триггер | Рекламная кампания, всплеск трафика | Новый фильтр/отчёт без индекса | Обмен с 1С, ручной запуск агента, ошибка в коде агента |
| Что смотреть для подтверждения | Статус пула, error.log nginx | Slow query log, SHOW PROCESSLIST | Список PHP-процессов, лог агентов Битрикс |
Сценарий 1: исчерпан пул php-fpm
Классическая картина: трафик вырос (рекламная кампания, попадание в выдачу, рассылка), число одновременных запросов превысило pm.max_children, новые запросы встают в очередь и в итоге падают по таймауту. Статус пула показывает active processes, равное лимиту, и растущий listen queue; в error.log nginx — записи «no live upstreams» или «upstream timed out» пачками.
Важно: само по себе исчерпание пула — не всегда «неправильная настройка». Иногда это честный сигнал, что текущая конфигурация сервера (объём памяти, число ядер CPU) не рассчитана на выросший трафик, и pm.max_children уже стоит близко к физическому пределу — поднимать его дальше без апгрейда сервера означает просто перейти от 502/504 к нехватке памяти и OOM-убийствам воркеров.
Сценарий 2: медленный SQL-запрос
Пул php-fpm не исчерпан, но запросы к сайту всё равно долго выполняются или падают по 504 — воркеры не заняты «количеством», они заняты «одним долгим запросом». В slow query log MySQL находится конкретный SQL с большим числом просмотренных строк — часто это новый фильтр в каталоге без индекса на нужное свойство, отчёт админки, который строит выборку по всей таблице заказов, или запрос, порождённый некорректно настроенным умным фильтром без фасетного индекса.
Отличительная черта этого сценария — нагрузка на CPU концентрируется в процессе MySQL, а не размазывается по множеству PHP-процессов. top или htop в момент инцидента покажет один или несколько процессов mysqld, потребляющих непропорционально много CPU относительно PHP-процессов.
Сценарий 3: зациклившийся агент
Агенты 1С-Битрикс (CAgent) — фоновые задачи, которые платформа запускает по расписанию при обращении посетителя к сайту (или через отдельный cron-вызов agents_cron.php, что предпочтительно на нагруженных проектах, чтобы не привязывать выполнение агента к случайному запросу живого пользователя). Если агент содержит ошибку в логике (бесконечный цикл, рекурсивный вызов без условия выхода) или просто стал слишком тяжёлым по мере роста данных (например, агент пересчёта остатков на разросшемся каталоге), он может выполняться минутами, удерживая один PHP-процесс и создавая нагрузку на CPU и базу параллельно с обычными запросами посетителей.
Отличить этот сценарий помогает совпадение по времени: если скачок CPU и рост медленных запросов начались ровно в момент, когда по расписанию должен был сработать конкретный агент (или запустился обмен с 1С по cron) — это сильный указатель на источник. Список зарегистрированных агентов и время их последнего/следующего запуска виден в административном разделе «Настройки → Агенты».
agents_cron.php в часы низкой нагрузки — это разводит фоновую работу и обслуживание посетителей физически по разным процессам.
Немедленная митигация против решения первопричины
В момент инцидента важно не путать две разные задачи: вернуть сайт в рабочее состояние прямо сейчас и разобраться, почему это случилось, чтобы не повторилось. Смешение этих задач — частая ошибка: команда тратит время на глубокий разбор причины, пока сайт лежит для всех посетителей, хотя быстрая митигация заняла бы минуту.
- Перезапустите php-fpm. Команда вида
systemctl restart php-fpm(или соответствующий сервис для используемой версии PHP) сбрасывает все зависшие воркеры и почти всегда возвращает сайт в рабочее состояние за секунды. Это безопасная и обратимая операция. - Если проблема в конкретном затянувшемся запросе — найдите и остановите его. В MySQL это
KILL <id процесса>по даннымSHOW PROCESSLIST; для php-скрипта — определите и завершите конкретный PHP-процесс, а не весь пул. - Зафиксируйте состояние до перезапуска. Сохраните вывод статуса php-fpm, актуальный кусок error.log и slow query log за период инцидента — после перезапуска эти данные частично теряются, а без них найти первопричину будет заметно сложнее.
- Убедитесь, что сайт действительно стабилен, а не «временно ожил». Проверьте несколько ключевых страниц (главная, карточка товара, корзина) и понаблюдайте за метриками 10–15 минут — иногда перезапуск лишь откладывает повтор на те же условия.
- Только после стабилизации переходите к разбору первопричины по логам, зафиксированным на шаге 3, и планируйте постоянное исправление — индекс, увеличение
pm.max_children, перенос агента на ночное расписание.
Если исчерпание пула php-fpm или медленные запросы повторяются регулярно, а не разово, — это уже не про «потушить пожар», а про системный анализ медленных запросов и производительности проекта в целом: разовые перезапуски не масштабируются на растущий трафик.
Реализация в 1С-Битрикс: монитор производительности
Помимо логов веб-сервера и MySQL, у самого 1С-Битрикс есть встроенный инструмент — модуль «Монитор производительности» (perfmon), который собирает статистику по времени выполнения хитов, числу и времени SQL-запросов, попаданиям в кэш прямо на уровне приложения. Он не заменяет системные логи, но даёт взгляд «изнутри» кода Битрикса — какие конкретно компоненты и запросы вносят основной вклад в время генерации страницы.
Отдельно в админке полезен раздел с логом ошибок PHP самого Битрикса («Настройки → Инструменты → Журнал событий» и лог ошибок скриптов) — он фиксирует фатальные ошибки и предупреждения PHP уровня приложения, которые не всегда попадают в системный error.log в явном виде. При разборе инцидента имеет смысл сверить время из этого журнала с временными метками из nginx, php-fpm и MySQL — совпадение по минутам почти всегда указывает на общую причину.
Что должен был поймать мониторинг заранее
Большинство инцидентов 502/504 не возникают мгновенно — им предшествует период деградации в 15–40 минут, который просто некому было заметить без настроенных алертов. Базовый набор метрик, которые стоит мониторить на BitrixVM, чтобы получать сигнал до, а не после падения сайта:
| Метрика | Источник | Разумный порог алерта |
|---|---|---|
| Listen queue php-fpm | Статус пула | Больше 0 дольше 2–3 минут подряд |
| Число медленных запросов MySQL в минуту | Slow query log | Резкий рост относительно суточной нормы |
| Время ответа сайта снаружи | Внешний HTTP-мониторинг | Выше нормы 3 проверки подряд |
| Загрузка CPU и память сервера | Системный мониторинг (Zabbix, Prometheus и аналоги) | Устойчиво выше 80–85% |
| Коды ответа 5xx в access-логе nginx | access.log / статистика nginx | Доля 5xx выше обычного фона |
Ключевой принцип — мониторинг должен покрывать всю цепочку «nginx → php-fpm → MySQL → сервер целиком», а не одну точку. Алерт только по загрузке CPU не расскажет, что причина в конкретном запросе без индекса; алерт только по времени ответа сайта не подскажет, где именно искать. Комплект метрик из таблицы вместе с грамотной настройкой и управлением BitrixVM сокращает время диагностики инцидента с часов до минут — потому что нужные данные уже собраны к моменту, когда вы открываете панель.
Частые ошибки при диагностике
- Сразу перезапускают весь сервер «на всякий случай», теряя логи и состояние, по которым можно было найти первопричину.
- Смотрят только на CPU и делают вывод «сервер слабый», не проверив, что именно грузит процессор — трафик, один SQL-запрос или зациклившийся агент.
- Поднимают
pm.max_childrenвслепую, не проверив объём доступной памяти — итог: вместо 502/504 получают OOM killer, который убивает воркеры пачками. - Не сверяют временные метки между логами nginx, php-fpm, MySQL и журналом событий Битрикса — и упускают совпадение по времени, которое сразу указывает на источник.
- Отключают slow query log «чтобы не мешал», хотя нужно было лишь временно понизить
long_query_timeна период диагностики. - Игнорируют агентов и cron-задачи как источник нагрузки, считая, что раз «код не менялся» — проблема не в нём, хотя данные, над которыми работает агент, могли вырасти в разы.
- Не документируют разбор инцидента — тот же сценарий повторяется через месяц, и диагностика начинается заново с нуля.
fastcgi_read_timeout, но это не решение, а маскировка: запрос всё равно выполняется медленно, просто пользователь теперь ждёт дольше вместо мгновенной ошибки — а сервер держит воркер занятым ещё дольше, что при нагрузке скорее ускорит, а не отсрочит исчерпание пула.
Чек-лист реагирования на инцидент
Порядок действий, который стоит держать под рукой (в идеале — в виде отдельного runbook-документа команды), чтобы не терять время на импровизацию в момент, когда сайт уже лежит:
- Зафиксируйте факт и время начала инцидента. По внешнему мониторингу или первому обращению — это точка отсчёта для сверки логов.
- Проверьте статус пула php-fpm. Active processes и listen queue сразу подскажут, исчерпан ли пул.
- Проверьте SHOW PROCESSLIST в MySQL. Ищите долгие или заблокированные запросы.
- Сохраните срез логов за период инцидента. error.log nginx, slow log php-fpm, slow query log MySQL — до любых перезапусков.
- Примените немедленную митигацию. Перезапуск php-fpm или снятие конкретного зависшего запроса.
- Проверьте стабильность 10–15 минут. Не считайте инцидент закрытым сразу после первого «сайт открылся».
- Найдите первопричину по сохранённым логам. Сопоставьте временные метки со всеми источниками, включая агентов и cron.
- Устраните первопричину и обновите мониторинг. Добавьте индекс, перенесите тяжёлую задачу на ночь, поднимите лимит осознанно — и добавьте алерт, который поймает похожую ситуацию раньше в следующий раз.
Вывод
502 и 504 на BitrixVM почти никогда не возникают «просто так» — за ними стоит конкретный, находимый по логам процесс: исчерпанный пул php-fpm, медленный SQL-запрос без индекса или зациклившийся агент. Быстрая диагностика строится на трёх источниках — error.log nginx, статус и slow log php-fpm, slow query log MySQL — и на умении не путать немедленную митигацию с устранением первопричины. А хорошо настроенный мониторинг переводит большинство таких инцидентов из разряда «внезапное падение сайта» в разряд «плановое вмешательство по алерту», пока покупатели вообще ничего не заметили.