Агенты в Битрикс и cron на сервере - два инструмента для одной задачи: выполнить код в фоне без участия пользователя. За несколько лет работы с проектами на 1С-Битрикс я обычно ставлю связку из обоих механизмов - агенты живут внутри ядра CMS и по умолчанию запускаются при хитах на сайт, а cron дёргает агентское расписание Битрикс напрямую через php_cli, без зависимости от посещаемости. В статье - как настроить агенты и cron в Битрикс так, чтобы фоновые задачи выполнялись по расписанию, а не «когда кто-то случайно зашёл на сайт ночью».
Чем агенты Битрикс отличаются от системного cron
Агент в Битрикс - это PHP-функция, зарегистрированная в таблице b_agent, с полями ACTIVE, INTERVAL и NEXT_EXEC. По умолчанию ядро проверяет эту таблицу на каждом хите: зашёл пользователь на сайт - сработал prolog, сработала проверка агентов, если время пришло - функция выполнилась. Это удобно на старте, потому что не нужен доступ к серверу и crontab, но на сайте с низким трафиком ночью агент с интервалом в час может выполниться с опозданием на несколько часов, а на сайте с высокой посещаемостью - создать пиковую нагрузку, если несколько тяжёлых агентов совпадают по времени с наплывом трафика.
Системный cron работает независимо от посещаемости: он вызывает PHP-скрипт по расписанию через crontab на сервере. Для Битрикс это файл bitrix/php_cli/agents.php, который поднимает ядро в CLI-режиме и вызывает CAgent::CheckAgents() - по сути ту же логику, что и на хите, но без привязки к запросу пользователя.
| Критерий | Агент на хитах | Агент + cron |
|---|---|---|
| Точность расписания | Зависит от трафика | Секунды-минуты |
| Нагрузка на сайт | Пики совпадают с посещаемостью | Равномерная, отдельно от хитов |
| Нужен доступ к серверу | Нет | Да, для crontab |
| Подходит для | Тестовых и некритичных задач | Интеграций, рассылок, синхронизаций |
На практике для интернет-магазинов и сервисов с интеграциями (обмен с CRM, статусы доставки, уведомления) я всегда перевожу агенты на cron ещё на этапе настройки продакшена - тестировать логику на хитах можно, но в проде это создаёт непредсказуемую задержку выполнения.
Как зарегистрировать агент в Битрикс: код
Агент регистрируется вызовом CAgent::AddAgent - обычно это делают в install-файле модуля или разово через консоль администратора.
<?php
CAgent::AddAgent(
"MyAgentSyncCdek();", // имя функции с ()
"main", // модуль, к которому привязан агент
"N", // период (N — обычный интервальный режим)
900, // интервал в секундах между запусками
"", // дата первого выполнения (пусто — сразу)
"Y", // активен
date("d.m.Y H:i:s", time() + 900), // время следующего запуска
100 // сортировка
);
Сама функция должна быть доступна в момент выполнения (объявлена в подключаемом модулем файле) и обязательно возвращать строку с вызовом самой себя - без этого агент выполнится один раз и отключится:
function MyAgentSyncCdek()
{
$result = SyncCdekOrderStatuses();
if (!$result) {
AddMessage2Log("MyAgentSyncCdek: ошибка синхронизации со СДЭК", "main");
}
return "MyAgentSyncCdek();";
}
Эту ошибку - забыть return с точкой с запятой в конце строки - я видел у клиентов чаще всего: агент числится активным в базе, но фактически выполняется один раз при регистрации и молчит месяцами, пока кто-то не заметит, что синхронизация встала.
Бесплатный материал
🎁 Полезный скрипт в подарок
Подпишитесь на Telegram - пришлю готовый скрипт по этой теме.
Без спама. Отписка в 1 клик.
Настройка cron для агентского расписания Битрикс
Чтобы агенты не зависели от хитов, в панели администратора идём в Настройки → Агенты и ставим галочку «Использовать crontab» - с этого момента ядро перестаёт проверять таблицу b_agent на каждом запросе пользователя. Дальше на сервере добавляем задачу в crontab:
*/5 * * * * /usr/bin/php /home/bitrix/www/bitrix/php_cli/agents.php >/dev/null 2>&1
Запуск раз в 5 минут - рабочий компромисс для большинства проектов: агент с интервалом 900 секунд (15 минут) выполнится с погрешностью максимум в 5 минут, а нагрузка на сервер от самого cron-вызова минимальна, потому что CheckAgents проверяет таблицу и пропускает всё, для чего время ещё не пришло. Для задач, где важна секундная точность (например, отправка сообщения в момент наступления события), агенты вообще не лучший инструмент - там я обычно ставлю отдельный crontab-вызов конкретного PHP-скрипта или очередь через RabbitMQ.
Важно проверить, что php_cli использует ту же версию PHP и те же настройки php.ini, что и веб-сервер - иначе агент, работающий на сайте, может падать в cron из-за отсутствия расширения или другого memory_limit. На хостингах с несколькими версиями PHP это частая причина, почему «агент вроде настроен, а данные не обновляются».
Частые ошибки при настройке фоновых задач в Битрикс
- Функция агента не возвращает строку самовызова - агент выполняется один раз и «засыпает» навсегда, оставаясь ACTIVE в базе.
- Галочка «Использовать crontab» включена, а сам crontab на сервере не настроен - агенты просто перестают выполняться вообще, потому что и хиты их больше не триггерят, и cron не вызывается.
- Несколько записей в crontab дублируют вызов agents.php - агент с коротким интервалом может выполниться дважды подряд, что критично для операций записи (двойное списание остатков, повторная отправка уведомления).
- Тяжёлый агент (парсинг большого XML, синхронизация тысяч позиций) упирается в max_execution_time при выполнении через веб-сервер - в php_cli это ограничение обычно не действует, но если запуск идёт через wget или curl на публичный URL, лимит веб-сервера снова в игре.
- Часовой пояс сервера не совпадает с часовым поясом, который ожидает бизнес-логика - агент, привязанный к «концу рабочего дня», срабатывает не в 18:00, а в 15:00 по UTC.
Мониторинг и логирование выполнения агентов
Проверить, что агент реально отрабатывает, можно прямо в базе - поле LAST_EXEC в таблице b_agent показывает время последнего запуска, а разница между NEXT_EXEC и текущим временем подскажет, накапливается ли отставание. Для продакшен-проектов я обычно добавляю логирование через AddMessage2Log с указанием модуля, чтобы ошибки агентов попадали в общий журнал событий Битрикс и были видны в Настройки → Журнал событий, а не терялись в error_log сервера вперемешку с остальным.
Для критичных интеграций - синхронизация остатков, обмен заказами, статусы оплаты - одного журнала внутри CMS недостаточно: если агент падает молча, узнают об этом обычно клиенты, когда заказ не пришёл. Практика, которая себя оправдала: при ошибке в функции агента дополнительно отправлять сообщение в отдельный Telegram-чат для разработчиков через простого aiogram-бота или вебхук - уведомление приходит за секунды, а не после жалобы клиента. Для части клиентов такие цепочки мониторинга я собираю через автоматизацию в n8n - туда удобно выносить логику ретраев и алертов, не раздувая код самого модуля Битрикс.
Практические примеры: интеграции и уведомления
Синхронизация статусов доставки СДЭК
Типовая задача для интернет-магазина: раз в 15 минут агент опрашивает API СДЭК по номерам активных отправлений и обновляет статус заказа в Битрикс. Делать это на каждом хите бессмысленно - статус доставки не меняется по несколько раз в минуту, а лишние обращения к внешнему API увеличивают риск упереться в лимиты. С cron-расписанием интервал предсказуем, и легко посчитать нагрузку: при 200 активных отправлениях и интервале в 15 минут это около 20 запросов в минуту к API СДЭК, что укладывается в лимиты большинства тарифов.
Уведомления и отчёты
Агент, который раз в сутки в 9:00 собирает сводку по заказам за прошедшие сутки и отправляет её менеджеру в Telegram - ещё один частый запрос. Реализуется тем же агентом с интервалом 86400 секунд и функцией, которая формирует выборку из b_sale_order и дёргает Telegram Bot API. Если отчётов и интеграций набирается много и логика начинает разрастаться внутри модуля Битрикс, часть из них выгоднее вынести за пределы CMS - например, отдельным Python-скриптом по cron на сервере, без нагрузки на ядро Битрикс вообще. Готовые заготовки таких скриптов для типовых интеграций я собираю в библиотеке готовых скриптов.
Когда агентов Битрикс лучше не трогать вообще
Если задача не завязана на данные внутри CMS (например, сбор цен конкурентов или мониторинг курса валют для внешнего дашборда), проще и надёжнее вызывать отдельный скрипт напрямую через crontab, минуя ядро Битрикс - это быстрее по времени выполнения и не тянет за собой инициализацию всей CMS ради простого HTTP-запроса.
Чтобы сайт работал без сбоев
Техподдержка
от 15 000 ₽/мес
Подробнее →Частые вопросы
Чем агент Битрикс отличается от crontab-задачи на сервере?
Агент - это механизм внутри ядра Битрикс: функция регистрируется в таблице b_agent и по умолчанию проверяется на каждом хите сайта. Crontab-задача - системный планировщик Linux, который вызывает скрипт независимо от посещаемости. На практике их комбинируют: агент описывает бизнес-логику и хранится в базе Битрикс, а crontab вызывает bitrix/php_cli/agents.php, чтобы агент выполнялся по расписанию, а не по хитам.
Как проверить, что агент реально выполняется по расписанию?
Посмотреть поля LAST_EXEC и NEXT_EXEC в таблице b_agent - если LAST_EXEC не обновляется, значит выполнение не срабатывает вообще (проблема с crontab или php_cli) либо функция агента падает с ошибкой раньше, чем доходит до записи лога. Второй способ - включить логирование через AddMessage2Log внутри самой функции и смотреть Журнал событий в панели администратора.
Можно ли использовать n8n вместо агентов Битрикс?
Для задач, не завязанных на внутренние сущности Битрикс (каталог, заказы, пользователи), n8n удобнее - там визуально настраивается расписание, ретраи и уведомления об ошибках без написания PHP-кода. Для операций, которые напрямую читают и пишут в таблицы Битрикс через его API (обновление остатков, статусов заказов), агент внутри самой CMS остаётся логичнее, потому что работает в том же окружении и с теми же правами.
Что делать, если агент завершается с ошибкой или зависает?
Первым делом проверить, что функция агента действительно возвращает строку самовызова - без этого агент отключается после первого запуска. Дальше - смотреть логи PHP и Журнал событий Битрикс на предмет исключений, и добавить try/catch внутри функции агента с логированием ошибки, чтобы одно необработанное исключение не блокировало все последующие агенты в цепочке CheckAgents.