HTTP 502 в Битрикс растёт из очереди агентов при живом сервере
Почему шлюз отдаёт 502 при спокойном железе: агенты держат PHP-воркеры; разница 502 и 504; вынос фона на cron.

Клиент пишет: «сайт не открывается». Вы заходите на VPS — CPU спокойный, MySQL не в потолке, nginx отвечает. А витрина и админка уже сыплют 502 или 504.
Частая причина на 1С-Битрикс — не «упало ядро», а занятый пул PHP-FPM. Тяжёлые агенты CAgent и длинный cron_events.php держат воркеры; новые запросы копятся в listen queue и отваливаются у шлюза. За 15 минут ниже — как это устроено, чем 502 отличается от 504 в этой схеме и как убрать фон с пользовательских хитов.
Речь про CMS «1С-Битрикс: Управление сайтом» и коробочный Битрикс24 на своём хостинге. Это ops-очередь PHP и агентов ядра, не Push/RTC и не «ИИ-агенты» из обзоров автоматизации.
Как проявляется: шлюз падает, железо «зелёное»
Типичная картина для интегратора:
- главная и админка периодически отдают 502 Bad Gateway или 504 Gateway Timeout;
- в error.log nginx встречается
upstream prematurely closed connection while reading response header from upstream; - нагрузка на БД умеренная — в публичных разборах бывало около 40% при полностью занятом FPM;
- OPcache и Composite уже включены, а отказы остаются.
Свежий контекст нагрузки: на Хабре (09.08.2026) разбирают контур 1С ↔ Битрикс24 со смарт-процессами, роботами, REST, cron-движком и очередями уведомлений. Чем больше фоновой автоматизации, тем выше шанс, что PHP-задачи конкурируют с обычными хитами за тот же пул — особенно если агенты ещё крутятся на посетителях или cron-прогон длинный и частый. Хабр здесь про рост фона, не готовый постмортем 502.
Агенты CAgent: что это и где смотреть
Агент — PHP-функция или метод, который ядро запускает по расписанию через CAgent::CheckAgents(). Список в админке: «Настройки → Инструменты → Агенты» (/bitrix/admin/agent_list.php). Данные лежат в таблице b_agent (поля вроде LAST_EXEC, NEXT_EXEC, RUNNING).
По умолчанию агенты могут выполняться на хитах посетителей: фон едет внутри HTTP-запроса пользователя. На малом сайте это терпимо. При нагрузке и «толстых» агентах страницы тормозят, а воркеры заняты не отдачей контента, а импортом, рассылкой или обменом.
Официальный путь BitrixVM / learning — перенести все агенты на cron.
В PHP-консоли выставьте флаги и убедитесь в ответе NN:
echo COption::SetOptionString("main", "agents_use_crontab", "N");
echo COption::SetOptionString("main", "check_agents", "N");
// ожидаемый вывод: NN
В dbconn.php уберите голые определения BX_CRONTAB_SUPPORT / BX_CRONTAB и добавьте защиту от хитов:
if (!(defined("CHK_EVENT") && CHK_EVENT === true)) {
define("BX_CRONTAB_SUPPORT", true);
}
Дальше — скрипт /bitrix/php_interface/cron_events.php с CHK_EVENT, вызовом CAgent::CheckAgents(), затем почтой/sender и прочим фоном по доке. В crontab — запуск раз в минуту или раз в 5 минут (путь к PHP CLI и DOCUMENT_ROOT — свои):
*/1 * * * * /usr/bin/php -f /path/to/bitrix/php_interface/cron_events.php
Перед правкой crontab проверьте бинарник: command -v php — major PHP должен совпадать с сайтом.
Документация прямо пишет: если новый запуск cron_events.php стартовал, пока предыдущий ещё работает, агенты не дублируются — блокируются на время выполнения. «Тяжёлым» в доке BitrixVM считают прогон дольше примерно 10 минут. Для CLI часто нет лимита времени скрипта; для веб-хитов в dbconn.php рекомендуют разный @set_time_limit (пример из доки: 600 для cli и 60 для web).
Почтовая очередь: параметр mail_event_bulk (дефолт часто 5). При росте писем поднимают (в доке встречается 20) и/или чаще крутят cron — иначе почтовый агент раздувает прогон.
PHP-FPM: откуда берутся 502 и 504
Цепочка простая: nginx → FastCGI → пул PHP-FPM. Свободный child берёт запрос. Когда все pm.max_children заняты, новые запросы копятся в listen queue (listen.backlog, часто 511). Переполнение или отказ принять — nginx отдаёт 502. Уже принятый запрос, который обрабатывается дольше fastcgi_read_timeout, чаще даёт 504.
В разборе Ivanpin (highload Bitrix) при акции трафик вырос втрое, TTFB был 8–12 с, порядка 600×504 в час; ps показывал ровно 5 php-fpm — типичный дефолт панелей вроде ISPmanager. Оценка пула:
pm.max_children ≈ (RAM_total − RAM_OS − RAM_MySQL) / RAM_per_php_process
Процесс Bitrix часто около 50–120 MB; в том кейсе около 68 MB — примерно 37–38 children на VPS 4 GB. После правки TTFB около 1.1 с, 504 ушли. Цифры из внешней статьи, не замеры BX Pulse.
Другой публичный постмортем (ParadigmaDev, 2BD): OPcache выключен + pm.max_children=5 + бот-шторм → 504; после opcache 512 MB, FPM 5→40 и APCu TTFB упал с 19.1 с до 0.28 с.
Мониторинг без внешних агентов — статус пула:
pm.status_path = /fpm-status
Смотрите listen queue, active processes против max_children, max listen queue.
Не делать: только поднимать fastcgi_read_timeout «чтобы не было 504» — очередь и память раздуваются сильнее.
Делать: смотреть fpm-status и b_agent.RUNNING до правок таймаутов nginx.
Чек-лист диагностики
| Уровень | Что проверить | Признак проблемы |
|---|---|---|
| PHP-FPM | /fpm-status: listen queue, active vs max_children |
listen queue > 0 постоянно; active ≈ max_children |
| Процессы | ps / число php-fpm children |
Ровно 5 (или другой жёсткий дефолт панели) на выделенном VPS с каталогом |
| Агенты | SQL по b_agent с RUNNING='Y'; время cron_events.php |
Долгий RUNNING; прогон > нескольких минут / > ~10 мин «тяжёлый» |
| Режим агентов | Опции agents_use_crontab / check_agents; crontab на cron_events |
Флаги под cron, а crontab нет — site checker ругается, фон «замирает» или остаётся на хитах |
| nginx | error.log на upstream / timeout | upstream prematurely closed… при долгой генерации vs короткому таймауту фронта |
| Почта / обмен | mail_event_bulk; размер порции импорта в агенте |
Очередь писем растёт; полный обмен 1С за один прогон вместо порций 100–300 |
Долгий агент — практичный минимум из community:
-- кто сейчас в RUNNING
SELECT ID, NAME, LAST_EXEC, NEXT_EXEC, RUNNING
FROM b_agent
WHERE RUNNING = 'Y'
ORDER BY LAST_EXEC;
time php -f /path/to/bitrix/php_interface/cron_events.php
Дополнительно — логирование OnAfterAgentExecute, чтобы видеть конкретный метод, а не только «cron висит».
Что менять после подтверждения
- Снять агентов с хитов по официальной схеме (флаги + dbconn + crontab). Без рабочего crontab «включить BX_CRONTAB_SUPPORT» недостаточно.
- Подогнать
pm.max_childrenпо формуле памяти, не копировать «40» вслепую с чужого VPS. - Разрезать тяжёлые агенты: обмен и импорт порциями, а не одним прогоном; почту — через
mail_event_bulkи частоту cron. - Включить OPcache, если выключен: в кейсе 2BD это было частью исправления 504 вместе с пулом.
- Таймауты nginx — после, не вместо пунктов выше.
Типичные ошибки ops: crontab с другим major PHP; дефолт max_children=5 на выделенном сервере; тяжёлый обмен внутри агента на хите; лечение только таймаутами без fpm-status и b_agent.
Частые вопросы
Почему 502, если MySQL и CPU в норме?
Узкое место — число и занятость php-fpm children. Когда пул полный, nginx не получает ответ от FastCGI вовремя или не может отдать новый запрос в очередь — получается 502/504, хотя БД ещё далека от потолка.
Чем 502 отличается от 504 при полном FPM?
502 чаще связан с тем, что шлюз не смог нормально получить ответ от upstream — в том числе при переполнении listen queue или обрыве соединения. 504 чаще значит: запрос уже ушёл в PHP, но обработка дольше fastcgi_read_timeout. На практике оба кода встречаются в одной аварии — смотрите fpm-status и логи вместе, не гадайте по одному коду.
Достаточно ли перенести агентов на cron, чтобы 502 исчезли?
Это обязательный шаг, если фон ещё едет на хитах, но не единственный. Длинный cron_events.php всё равно занимает CLI и ресурсы; при крошечном pm.max_children пользовательские запросы упрутся в пул и без агентов на хитах. Нужны и режим cron, и адекватный пул, и нарезка тяжёлых задач.
Как понять, какой агент «висит»?
Смотрите в b_agent строки с RUNNING='Y', замерьте time php -f …/cron_events.php и при необходимости повесьте обработчик OnAfterAgentExecute. В админке список агентов показывает расписание, но для инцидента важнее факт долгого RUNNING и длительность прогона.
Стоит ли сразу поднимать fastcgi_read_timeout?
Нет как первый шаг. Увеличение таймаута маскирует медленные запросы и сильнее забивает память и очередь. Сначала listen queue / max_children, долгие агенты и режим cron; таймауты — точечно под реальный профиль, когда пул уже адекватен.
Короткий вывод
Фон (агент или cron_events) держит PHP → пул FPM заполнен → listen queue растёт → nginx отдаёт 502/504 при ещё «живом» железе. Лечение — агенты на cron по доке, честный max_children, нарезка тяжёлых прогонов и статус пула до кручения таймаутов.
BX Pulse следит за доступностью и техническим состоянием проектов на 1С-Битрикс и помогает замечать отказы шлюза и деградацию ответа до обращения клиента — в том числе когда сервер выглядит нормально, а витрина уже сыплет 502.
Источники
- Хабр: «Виртуальные сотрудники» — 1С и Битрикс24, автоматизация и очереди (09.08.2026)
- 1С-Битрикс learning: перевод всех агентов на Cron
- Ivanpin: php-fpm max_children и highload Bitrix
- ParadigmaDev: разбор 504 (OPcache + FPM)
- Nikovit: как найти долго выполняющийся агент
- Fornex: агенты Битрикс через cron