БесплатноБазовая интеграция с 1С в подарок при заказе интернет-магазина под ключ

Диагностика 502/504 и высокого CPU на BitrixVM: разбор инцидента

Диагностика ошибок 502 и 504 и высокого CPU на BitrixVM: логи nginx, php-fpm и MySQL, монитор производительности

Сайт отвечает 502 или 504, в панели мониторинга красным горит «сервер недоступен», в чате уже пишут менеджеры — а в логах на первый взгляд ничего не понятно: тысячи строк, десяток процессов php-fpm, MySQL показывает какую-то активность. Именно в эти первые пять минут решается, займёт разбор десять минут или два часа простоя магазина.

Ниже — практический маршрут диагностики 502/504 и высокого CPU на BitrixVM: куда смотреть в первую очередь, как отличить исчерпание пула php-fpm от медленного SQL-запроса и от зациклившегося агента 1С-Битрикс, и что делать немедленно, а что — уже после того, как сайт снова открывается. Материал написан по нашей практике диагностики ошибок 502/504 и высокого CPU на BitrixVM — без общих слов про «проверьте логи».

Коротко

  • 502 — php-fpm ответил некорректно или упал; 504 — php-fpm вообще не успел ответить за отведённое время.
  • Диагностику начинайте с трёх источников: error.log nginx, статус пула и 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 — на «что-то не успевает».

Важно: высокий CPU на сервере — не причина, а следствие. Загрузка процессора растёт либо из-за реального роста трафика, либо из-за одного тяжёлого процесса (медленный запрос, зациклившийся скрипт), который «съедает» ресурсы у остальных. Задача диагностики — понять, какой именно процесс перегружает систему, а не просто зафиксировать факт высокого CPU.

Три лога, с которых начинается любая диагностика

На BitrixVM инцидент почти всегда виден на пересечении трёх источников. Каждый закрывает свою зону ответственности в цепочке запроса, и вместе они дают полную картину.

Браузер nginx error.log php-fpm status, slow log MySQL slow log Что смотреть на каждом узле nginx — коды ответов апстрима, "upstream timed out", "no live upstreams" php-fpm — active processes vs pm.max_children, listen queue, slow log с трассировкой MySQL — long_query_time в slow log, SHOW PROCESSLIST, блокировки InnoDB
Схема: запрос проходит через nginx, php-fpm и MySQL — на каждом узле свой лог и свой диагностический признак проблемы.

nginx error.log: как читать 502 и 504

Первым делом открывайте error.log nginx (типовой путь на BitrixVM — /var/log/nginx/error.log или журнал конкретного виртуального хоста в bx/scripts окружении). Ищите записи в момент инцидента с характерными фразами:

Важная деталь: в 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 nginxSlow 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) — это сильный указатель на источник. Список зарегистрированных агентов и время их последнего/следующего запуска виден в административном разделе «Настройки → Агенты».

Совет: тяжёлые и потенциально долгие операции (полная переиндексация каталога, массовый пересчёт, большой обмен с 1С) стоит выносить из обработчиков живых запросов и агентов, привязанных к хитам сайта, в отдельные cron-задачи, выполняемые через agents_cron.php в часы низкой нагрузки — это разводит фоновую работу и обслуживание посетителей физически по разным процессам.

Немедленная митигация против решения первопричины

В момент инцидента важно не путать две разные задачи: вернуть сайт в рабочее состояние прямо сейчас и разобраться, почему это случилось, чтобы не повторилось. Смешение этих задач — частая ошибка: команда тратит время на глубокий разбор причины, пока сайт лежит для всех посетителей, хотя быстрая митигация заняла бы минуту.

  1. Перезапустите php-fpm. Команда вида systemctl restart php-fpm (или соответствующий сервис для используемой версии PHP) сбрасывает все зависшие воркеры и почти всегда возвращает сайт в рабочее состояние за секунды. Это безопасная и обратимая операция.
  2. Если проблема в конкретном затянувшемся запросе — найдите и остановите его. В MySQL это KILL <id процесса> по данным SHOW PROCESSLIST; для php-скрипта — определите и завершите конкретный PHP-процесс, а не весь пул.
  3. Зафиксируйте состояние до перезапуска. Сохраните вывод статуса php-fpm, актуальный кусок error.log и slow query log за период инцидента — после перезапуска эти данные частично теряются, а без них найти первопричину будет заметно сложнее.
  4. Убедитесь, что сайт действительно стабилен, а не «временно ожил». Проверьте несколько ключевых страниц (главная, карточка товара, корзина) и понаблюдайте за метриками 10–15 минут — иногда перезапуск лишь откладывает повтор на те же условия.
  5. Только после стабилизации переходите к разбору первопричины по логам, зафиксированным на шаге 3, и планируйте постоянное исправление — индекс, увеличение pm.max_children, перенос агента на ночное расписание.

Если исчерпание пула php-fpm или медленные запросы повторяются регулярно, а не разово, — это уже не про «потушить пожар», а про системный анализ медленных запросов и производительности проекта в целом: разовые перезапуски не масштабируются на растущий трафик.

Реализация в 1С-Битрикс: монитор производительности

Помимо логов веб-сервера и MySQL, у самого 1С-Битрикс есть встроенный инструмент — модуль «Монитор производительности» (perfmon), который собирает статистику по времени выполнения хитов, числу и времени SQL-запросов, попаданиям в кэш прямо на уровне приложения. Он не заменяет системные логи, но даёт взгляд «изнутри» кода Битрикса — какие конкретно компоненты и запросы вносят основной вклад в время генерации страницы.

Настройки → Инструменты → Монитор производительности Среднее время хита 4,8 с SQL-запросов на хит 312 Попадание в кэш 61% Нагрузка за последний час пик — момент инцидента
Схема: монитор производительности Битрикс показывает всплеск среднего времени хита и числа 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-логе nginxaccess.log / статистика nginxДоля 5xx выше обычного фона

Ключевой принцип — мониторинг должен покрывать всю цепочку «nginx → php-fpm → MySQL → сервер целиком», а не одну точку. Алерт только по загрузке CPU не расскажет, что причина в конкретном запросе без индекса; алерт только по времени ответа сайта не подскажет, где именно искать. Комплект метрик из таблицы вместе с грамотной настройкой и управлением BitrixVM сокращает время диагностики инцидента с часов до минут — потому что нужные данные уже собраны к моменту, когда вы открываете панель.

Частые ошибки при диагностике

Мини-FAQ. Можно ли поставить общий таймаут побольше и «просто не видеть» 504? Технически можно увеличить fastcgi_read_timeout, но это не решение, а маскировка: запрос всё равно выполняется медленно, просто пользователь теперь ждёт дольше вместо мгновенной ошибки — а сервер держит воркер занятым ещё дольше, что при нагрузке скорее ускорит, а не отсрочит исчерпание пула.

Чек-лист реагирования на инцидент

Порядок действий, который стоит держать под рукой (в идеале — в виде отдельного runbook-документа команды), чтобы не терять время на импровизацию в момент, когда сайт уже лежит:

  1. Зафиксируйте факт и время начала инцидента. По внешнему мониторингу или первому обращению — это точка отсчёта для сверки логов.
  2. Проверьте статус пула php-fpm. Active processes и listen queue сразу подскажут, исчерпан ли пул.
  3. Проверьте SHOW PROCESSLIST в MySQL. Ищите долгие или заблокированные запросы.
  4. Сохраните срез логов за период инцидента. error.log nginx, slow log php-fpm, slow query log MySQL — до любых перезапусков.
  5. Примените немедленную митигацию. Перезапуск php-fpm или снятие конкретного зависшего запроса.
  6. Проверьте стабильность 10–15 минут. Не считайте инцидент закрытым сразу после первого «сайт открылся».
  7. Найдите первопричину по сохранённым логам. Сопоставьте временные метки со всеми источниками, включая агентов и cron.
  8. Устраните первопричину и обновите мониторинг. Добавьте индекс, перенесите тяжёлую задачу на ночь, поднимите лимит осознанно — и добавьте алерт, который поймает похожую ситуацию раньше в следующий раз.

Вывод

502 и 504 на BitrixVM почти никогда не возникают «просто так» — за ними стоит конкретный, находимый по логам процесс: исчерпанный пул php-fpm, медленный SQL-запрос без индекса или зациклившийся агент. Быстрая диагностика строится на трёх источниках — error.log nginx, статус и slow log php-fpm, slow query log MySQL — и на умении не путать немедленную митигацию с устранением первопричины. А хорошо настроенный мониторинг переводит большинство таких инцидентов из разряда «внезапное падение сайта» в разряд «плановое вмешательство по алерту», пока покупатели вообще ничего не заметили.

Частые вопросы

В чём разница между ошибками 502 и 504 на BitrixVM?

502 Bad Gateway означает, что nginx получил от апстрима (php-fpm) некорректный или пустой ответ — чаще всего php-fpm воркер упал, перезапустился или процесс был убит по превышению памяти. 504 Gateway Timeout означает, что апстрим не ответил вовсе за отведённое время — запрос выполнялся дольше, чем позволяет fastcgi_read_timeout в nginx, то есть php-fpm жив, но безнадёжно тормозит на конкретном запросе.

Как быстро понять, что дело именно в исчерпании пула php-fpm?

Откройте страницу статуса пула (обычно /status с параметром full, если она включена в конфиге) и посмотрите на поля active processes и listen queue. Если active processes равно pm.max_children и при этом listen queue растёт — пул исчерпан: все воркеры заняты, новые запросы встают в очередь и в итоге падают по таймауту с 502/504. Это же видно в error.log nginx по записям вида "upstream timed out" или "no live upstreams".

Почему на BitrixVM CPU может улетать в 100% без явного всплеска трафика?

Чаще всего это не трафик от посетителей, а фоновая задача: зациклившийся или слишком тяжёлый агент 1С-Битрикс (CAgent), запущенный по cron обмен с 1С, который совпал по времени с переиндексацией, или медленный SQL-запрос без нужного индекса, который MySQL выполняет полным сканированием таблицы. Отличить одно от другого помогает связка SHOW PROCESSLIST в MySQL и списка активных PHP-процессов на сервере — совпадение по времени запуска и длительности почти всегда указывает на источник.

Нужно ли сразу перезапускать php-fpm и MySQL при первых признаках 502/504?

Перезапуск php-fpm — рабочая мера немедленной митигации: он сбрасывает зависшие воркеры и возвращает сайт в рабочее состояние за секунды. Но это не решение проблемы, а обезболивающее: если не найти и не устранить первопричину (медленный запрос, зациклившийся агент, нехватка pm.max_children под текущую нагрузку), инцидент повторится в ближайшие часы или дни. Перезапуск MySQL — куда более рискованная операция, и её стоит делать только при явных признаках зависшей блокировки, а не «на всякий случай».

Какие настройки php-fpm чаще всего оказываются причиной инцидента на BitrixVM?

Три параметра стоит проверить в первую очередь: pm.max_children (сколько воркеров может работать одновременно — занижен относительно реальной нагрузки), request_terminate_timeout (через сколько секунд php-fpm принудительно убьёт зависший запрос — если не задан, один тяжёлый запрос может держать воркер бесконечно) и pm.max_requests (после скольких запросов воркер перезапускается — помогает от утечек памяти в долгоживущих процессах).

Как мониторинг мог бы предупредить об инциденте заранее?

Метрики, которые обычно показывают проблему за 15–40 минут до полного падения сайта: рост listen queue на статусе php-fpm, рост числа медленных запросов в slow query log MySQL, рост времени ответа (response time) на внешнем мониторинге доступности и рост загрузки CPU/памяти на сервере в целом. Алерт по любой из этих метрик с порогом «выше нормы на 10–15 минут подряд» даёт время вмешаться до того, как сайт реально ляжет для всех посетителей.

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

Сайт периодически отдаёт 502/504 или «падает» под нагрузкой?

Разберём логи, найдём первопричину — пул php-fpm, медленный запрос или агент — и настроим мониторинг BitrixVM, чтобы следующий инцидент поймали раньше, чем его заметят покупатели.

Услуга «Диагностика 502/504»

Игорь Воскресенский

Основатель студии B2Bsite. С 2014 года команда разрабатывает и поддерживает интернет-магазины и корпоративные сайты на 1С-Битрикс, настраивает каталоги, умный фильтр и обмен с 1С для среднего и крупного бизнеса.

← Все статьи блога