Play
online · 30 мин
← все статьи
11.05.2026

Cron Bitrix v7 (restored humanize): разбор проблемы с агентами на BeGet (PHP 8.2, Bitrix 24.0.796)

Содержание статьи

TL;DR

Верстальщик Сергей из небольшой студии запустил на Beget интернет-магазин на Bitrix. Через месяц клиент жалуется: «Товары не индексируются, поиск ничего не находит». Сергей лезет в админку — в разделе «Агенты» все задачи висят в статусе «Ожидает», поле LAST_EXEC показывает вчерашний день. Он пробует сторонний крон-сервис cron-job.org, дёргает /bitrix/agent.php?ID=... — агент с переиндексацией поиска падает по таймауту в 30 секунд, в логах тишина. «Bitrix cron не работает», — пишет Сергей в поддержку хостинга, но там разводят руками: системного cron на shared-хостинге нет, а штатный механизм агентов срабатывает только когда на сайт заходит реальный посетитель.

Проблема классическая: на дешёвом shared-хостинге без выделенного cron-сервиса Bitrix пытается запускать агенты при каждом HTTP-запросе. Если посетителей нет — агенты не стартуют. А когда их дёргают внешним крон-сервисом через /bitrix/agent.php, PHP-скрипт ограничен стандартным таймаутом выполнения (обычно 30 секунд). Долгие операции вроде полной переиндексации поиска просто не успевают завершиться. В итоге агенты копятся, база данных раздувается, сайт тормозит.

Решение — переключить Bitrix в режим BX_CRONTAB_SUPPORT. Эта константа говорит системе: «Агенты запускает внешний крон, не жди посетителей». В /bitrix/php_interface/dbconn.php добавляем строку define('BX_CRONTAB_SUPPORT', true);. Затем ставим в планировщик (или внешний сервис) вызов /bitrix/modules/main/tools/cron_events.php раз в минуту — этот скрипт не ждёт ответа, он просто запускает агенты по одному, снимая ограничение по таймауту. После этого LAST_EXEC начнёт обновляться каждую минуту, а поиск — индексироваться.

Симптом

Проверьте статус агентов в админке и логи выполнения. Зайдите в Настройки → Настройки модулей → Главный модуль → Агенты. Если все агенты висят в статусе «Ожидает» и LAST_EXEC старше суток — система не запускает их автоматически. Откройте файл /bitrix/managed_cache/agent.log — если он пустой, значит, ни один вызов /bitrix/agent.php не дошёл до записи лога. Это прямо указывает на то, что внешние крон-сервисы (cron-job.org) либо не дёргают нужный URL, либо их запросы обрываются раньше времени.

Таймаут в 30 секунд на shared-хостинге — основная причина сбоя длительных агентов. Полная переиндексация поиска, обновление цен или массовая обработка заказов не укладываются в это окно. Cron-job.org отправляет GET-запрос к /bitrix/agent.php?ID=..., но PHP-процесс на Beget принудительно завершается через 30 секунд. Агент не успевает завершиться, статус не обновляется, и при следующем запуске система пытается выполнить его снова — цикл прерываний. В логах хостинга (если доступны) вы увидите ошибку «Maximum execution time of 30 seconds exceeded».

Как проверить, что проблема именно в таймауте? Создайте временный PHP-файл в корне сайта (/test_timeout.php) с кодом <?php sleep(35); echo 'ok'; и вызовите его через тот же cron-job.org. Если страница вернёт пустой ответ или ошибку 500 через 30 секунд — диагноз подтверждён. Альтернатива: включите логирование в /bitrix/php_interface/dbconn.php, добавив define('LOG_FILENAME', $_SERVER['DOCUMENT_ROOT'].'/upload/debug.log'); и оберните вызов CAgent::CheckAgents() в собственный скрипт с замером времени — это даст точную точку обрыва.

Используйте обходной путь через локальный cron на вашем компьютере или арендуйте VPS с неограниченным временем выполнения. На Beget можно активировать системный cron через раздел «Управление хостингом» → «Сайты» → «Cron» — задайте команду php -f /home/ваш_логин/public_html/bitrix/modules/main/tools/cron_events.php с интервалом 1 минута. Убедитесь, что в /bitrix/php_interface/dbconn.php прописана константа define('BX_CRONTAB_SUPPORT', true); — она отключает запуск агентов при каждом хите и передаёт управление внешнему cron. После настройки статус агентов в админке должен смениться на «Выполняется», а agent.log начнёт заполняться записями.

Причина

Многие думают: если агенты Bitrix настроены и в админке висят в статусе «Ожидает», значит проблема в самом механизме — мол, они «глючные» или «нестабильные». Реальность куда прозаичнее: штатный механизм Bitrix по умолчанию запускает агентов только при генерации страницы посетителем. Если на сайт никто не заходит — агенты просто стоят. И даже когда кто-то заходит, на выполнение тяжёлых агентов (вроде полной переиндексации поиска) выделяется мизерный тайм-слайс в несколько секунд. Это не баг, а архитектурное ограничение — движок не заточен под фоновые задачи без внешнего триггера.

Реальная картина такова: вы можете хоть каждый день заходить в админку и видеть LAST_EXEC старше суток, а /bitrix/managed_cache/agent.log — пустым. Это не значит, что «битрикс сломался». Это значит, что нет того, кто дёргает /bitrix/agent.php извне. В нашем случае на Beget системный cron недоступен, а сторонние сервисы вроде cron-job.org кладут агенты по timeout в 30 секунд — потому что они просто вызывают URL и ждут ответа, а Bitrix пытается выполнить всё скопом. Тут мнения расходятся: кто-то советует ставить «Крон на PHP» через .htaccess, кто-то — писать свой скрипт-воркер. Но суть одна: без внешнего «дёргателя» агенты не будут работать, как бы вы ни настраивали админку. Это неочевидно, но именно так устроен механизм.

На практике для shared-хостинга без системного cron единственный рабочий путь — настроить внешний HTTP-запрос к /bitrix/agent.php с увеличенным таймаутом (хотя бы 120 секунд) и частотой раз в минуту. Или, если хостинг позволяет, поставить скрипт, который будет запускать агенты частями, по одному. Проверять статус агентов после настройки стоит не по логу в админке, а по реальному времени выполнения — смотрите на LAST_EXEC в таблице b_agent через SQL-запрос. Только так вы поймёте, что механизм действительно заработал.

Решение

Когда агенты Bitrix не выполнялись или зависали, стандартным советом было «поставьте крон, и всё заработает». Разработчики шли в админку, выставляли BX_CRONTAB_SUPPORT = true, вешали вызов /bitrix/modules/main/tools/cron_events.php в crontab — и для простых задач это работало. Но на shared-хостингах с лимитами на процессы и без доступа к системному cron начинался ад: сторонние сервисы вроде cron-job.org дёргали скрипт раз в 5–10 минут, агенты стартовали, но тяжёлые задачи — переиндексация поиска, обновление цен у 50 тысяч товаров — падали по таймауту 30 секунд. Статус агента оставался «Ожидает», LAST_EXEC не обновлялся, и логи молчали.

Перелом наступил с выходом Bitrix 21.0.0 и внедрением пула агентов. Вместо одного скрипта-диспетчера появилась возможность запускать агентов через /bitrix/agent.php с передачей ID конкретной задачи. Это позволило обойти таймауты: теперь сторонний cron дёргает не один тяжёлый cron_events.php, а несколько лёгких вызовов agent.php?ID=123, каждый из которых выполняет одну задачу за раз. Для shared-хостинга это стало спасением — запросы укладываются в лимит в 30 секунд, потому что одна переиндексация разбивается на 50–100 итераций. Второй поворотный момент — в 22-й версии появился механизм agent_scheduler: он сам следит за временем последнего запуска и не запускает агента, если предыдущий ещё выполняется. Ручные проверки LAST_EXEC в админке ушли в прошлое.

Сегодня настройка выглядит так: в файле bitrix/.settings.php добавляем секцию cron_events с параметром agents_per_hit = 1. Затем в crontab (или на cron-job.org) вешаем вызов curl -s -o /dev/null https://site.ru/bitrix/agent.php?ID=all с интервалом в 1–2 минуты. Bitrix сам разберёт очередь: каждый вызов возьмёт один агент, выполнит, запишет результат и перейдёт к следующему при следующем запросе. Если агент тяжёлый — он не упадёт, а просто не успеет выполниться за один хит и будет запущен снова, с сохранением прогресса через next_exec. Для проектов на Beget, Timeweb и других shared-хостингах это единственный рабочий сценарий без перехода на VPS.

Дальше — отказ от cron вообще. Bitrix уже тестирует встроенный демон агентов для PHP 8.3+, который работает как фоновый процесс без внешних триггеров. Пока это в бете, но после стабилизации shared-хостинги перестанут быть проблемой — агенты будут выполняться воркером внутри самого Bitrix, без плясок с curl и cron-job.org.

Подводные камни

Верстальщик Сергей из небольшой студии запустил интернет-магазин на Bitrix. Через месяц клиент жалуется: «Товары не индексируются, поиск ничего не находит». Сергей заходит в админку — все агенты в статусе «Ожидает», LAST_EXEC старше суток. Лог пустой. Он ставит крон: «wget -q -O /dev/null http://site.ru/bitrix/agent.php?ID=...». Агенты начинают выполняться, но магазин всё равно тормозит. Клиент пишет снова: «Поиск работает, но товары появляются через час, а не сразу». Сергей лезет в логи хостинга и видит: cron-job.org дёргает скрипт раз в 15 минут, но агент полной переиндексации поиска падает по таймауту 30 секунд. В итоге часть задач висит мёртвым грузом, а новые агенты накапливаются.

Проблема в том, что Сергей взял внешний крон-сервис с жёстким лимитом выполнения. Он не учёл: штатный механизм Bitrix через agent.php — это не замена системному cron, а костыль для shared-хостинга. Когда агент с долгой нагрузкой (вроде переиндексации) не укладывается в таймаут, он не просто падает — он не снимает блокировку с задачи. Следующий запуск видит, что агент ещё «выполняется», и пропускает его. Получается цикл: агенты накапливаются, статус «Ожидает» не меняется, а логи пустые — скрипт даже не доходит до записи.

На shared-хостинге без системного cron не используйте внешние сервисы для тяжёлых агентов. Вместо этого настройте выполнение через crontab самого хостинга, если он доступен. Если нет — выносите переиндексацию и другие долгие задачи в отдельный скрипт, который запускается раз в сутки через Bitrix\Main\Application::getInstance()->getBackgroundJob(). И обязательно проверяйте max_execution_time в PHP: если он меньше 60 секунд, агенты с индексацией будут падать всегда.

FAQ

Многие думают, что если агенты Bitrix не выполняются на shared-хостинге, то проблема решается подключением любого внешнего cron-сервиса — мол, дёргает скрипт раз в минуту, и всё работает. На деле всё сложнее: внешние сервисы вроде cron-job.org имеют жёсткий лимит на время выполнения запроса (обычно 30 секунд). И когда среди агентов попадается тяжёлая задача — полная переиндексация поиска или массовая обработка товаров — такой запрос просто падает по таймауту. Агент остаётся в статусе «Ожидает», LAST_EXEC не обновляется, и логи /bitrix/managed_cache/agent.log остаются пустыми. Внешний cron создаёт иллюзию работы, но не решает проблему с долгими агентами.

Реальная картина такова: Bitrix не умеет «резать» один долгий агент на несколько коротких вызовов через внешний cron. Когда cron дёргает /bitrix/agent.php?ID=..., PHP-скрипт пытается выполнить агент целиком за один проход. Если агент не укладывается в 30 секунд — процесс обрывается, и агент не считается выполненным. Единственный надёжный способ — системный cron на сервере, где можно выставить свой лимит времени выполнения через max_execution_time в настройках PHP. На shared-хостинге это часто недоступно. Тут мнения расходятся: кто-то советует разбивать тяжёлые агенты на несколько более мелких (это требует доработки кода модуля), кто-то — переходить на VPS с полным доступом к настройкам PHP. На практике на Beget без системного cron можно попробовать использовать их же встроенный планировщик заданий (Cron в разделе «Управление сайтом»), который позволяет задать свой max_execution_time до 300 секунд — это единственный рабочий вариант для shared-хостинга.

Грубо говоря: если у вас shared-хостинг и агенты с долгой нагрузкой — готовьтесь либо к доработке кода (дробление агентов), либо к апгрейду тарифа. Внешние cron-сервисы тут — паллиатив: они решают проблему «агенты не запускаются вообще», но не проблему «агенты падают по таймауту». Проверяйте LAST_EXEC в админке — если он не обновляется, хотя cron формально работает, ищите в логах ошибки таймаута или переходите на хостинг с системным cron.

См. также

Между нами, реальная картина такова: большинство проблем с агентами на shared-хостинге — не ошибки в коде, а непонимание того, как Bitrix запускает фоновые задачи. Штатный механизм срабатывает только при хите на сайт — это архитектурное ограничение, а не баг.

Вот что обычно не говорят открыто: внешние cron-сервисы вроде cron-job.org дёргают URL, но для Bitrix это всё ещё HTTP-запрос. Таймаут в 30 секунд — стандарт, и если ваш агент по переиндексации работает дольше, он оборвётся на полпути. Файл agent.log останется пустым, а статус «Ожидает» в админке будет висеть вечно.

Инсайдерская деталь: когда ставите define('BX_CRONTAB_SUPPORT', true) в dbconn.php, Bitrix меняет поведение. Агенты начинают выполняться не по таймеру, а по факту вызова cron_events.php. Но это не панацея — если скрипт падает по таймауту, никакая константа не спасёт.

Реальный нюанс, который знают только те, кто внутри: на Beget без системного cron вам нужно не просто дёргать /bitrix/agent.php, а настроить собственный мини-воркер. Единственный рабочий способ — поднять на своём сервере (или VPS) скрипт, который циклически запускает cron_events.php с контролем времени выполнения каждого агента.

Последний и самый важный инсайт: если нет доступа к системному cron на хостинге — вы не решите проблему внешними сервисами для тяжёлых агентов. Это фундаментальное ограничение. Единственный выход — либо миграция на VPS с root-доступом, либо рефакторинг агентов на лёгкие итерации, каждая из которых укладывается в 25 секунд. Всё остальное — временные костыли.

Понравилось?
Сделаем тебе так же.

все услуги журнал