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

В Битрикс фоновая обработка часто начинается с агента: функция запускается раз в несколько минут и что-то делает. На десятках записей это работает, но при импорте каталога, отправке сотен уведомлений или синхронизации с внешней системой агент превращается в узкое место. Выбор между агентом, очередью в базе и RabbitMQ зависит не от моды, а от трёх параметров: длительности задачи, допустимой задержки и цены повторной обработки.
Сначала разделите агент и очередь
Агент — это планировщик. Он решает, когда вызвать PHP-функцию. Очередь — это место, где хранятся задания до выполнения, их состояние, число попыток и причина ошибки. Один агент может быть рабочим, который забирает задания из очереди, но сам по себе очередью не является.
В стандартном сценарии Битрикс агент вызывается либо в рамках обычного хита, либо отдельным cron-процессом. Первый режим проще включить, но выполнение зависит от посещаемости сайта и конкурирует с пользовательскими запросами. Второй стабильнее: запуск не ждёт посетителя, однако требует доступа к серверу и настройки расписания.
Агент отвечает на вопрос «когда попробовать», а очередь — на вопросы «что именно сделать», «что уже сделано» и «что повторить после ошибки».
Термин: идемпотентность — свойство операции, при котором повторный запуск не приводит к двойному результату. Например, повторная синхронизация заказа обновляет одну запись, а не создаёт второй заказ.
Три рабочих подхода
1. Один агент без отдельной очереди
Задание хранится прямо в данных Битрикс, а агент периодически выбирает, что обрабатывать. Такой вариант подходит для коротких операций: очистки временных данных, проверки небольшого числа записей, отправки единичных уведомлений.
В API ядра Битрикс 24.x и 25.x агент добавляют через CAgent::AddAgent. Имя класса и параметры могут отличаться в конкретном модуле, поэтому перед переносом кода проверьте сигнатуру в документации вашей версии:
<?php
CAgent::AddAgent(
'\\Vendor\\Example\\Agent::run();',
'vendor.example',
'N',
300,
'',
'Y'
);
Метод агента должен вернуть строку следующего вызова, если его нужно оставить активным. Пустой результат удаляет агент из дальнейшего выполнения. Это важная особенность: исключение или слишком долгий вызов не превращают обработку в надёжную очередь.
Цена простоты — слабый контроль. Если функция упала после отправки письма, но до записи результата, при следующем запуске она может отправить письмо повторно. Если функция выполняется дольше лимита PHP или cron запускается параллельно, появятся зависшие или дублирующиеся операции.
2. Очередь в таблице Битрикс
Задание сначала записывают в отдельную таблицу или подходящее хранилище модуля. Агент становится коротким worker-процессом: выбирает порцию новых строк, помечает их как взятые в работу, выполняет операцию и сохраняет результат.
Минимальный набор полей выглядит так:
- id — уникальный идентификатор задания;
- status — например, new, processing, done, error;
- payload — параметры задания в сериализованном или JSON-виде;
- attempts — число попыток;
- available_at — время, после которого задание можно брать снова;
- locked_at и worker_id — сведения о захватившем задачу процессе;
- last_error — последняя причина сбоя.
Главная защита от дублей — не просто выборка строк со статусом new, а атомарный захват. Два параллельных агента не должны получить одну запись. Для этого используют транзакцию, блокировку строк или обновление по условию, после которого проверяют число изменённых строк. Конкретный способ зависит от версии MySQL и слоя доступа к базе в вашем проекте.
Очередь в базе хороша, когда уже есть Битрикс, отдельный брокер поднимать не хочется, а потеря задания недопустима. Но она увеличивает нагрузку на ту же базу, где работают каталог, заказы и административная часть сайта.
3. Внешний брокер сообщений
RabbitMQ, Kafka или другой специализированный брокер отделяет фоновые задания от базы сайта. Битрикс публикует сообщение, а отдельный worker на PHP, Go или другом языке его потребляет. Это вариант для высокой частоты событий, нескольких потребителей и независимого масштабирования.
Цена — инфраструктура. Появляются подключения, мониторинг, права доступа, резервирование, политика повторов и отдельный процесс деплоя. Сам Битрикс не превращается автоматически в RabbitMQ-клиент: нужен проверенный пакет и собственный слой интеграции. Название библиотеки и способ подключения выбирайте под поддерживаемую версию PHP и официальную документацию выбранного брокера.
| Подход | Когда подходит | Что выигрываете | Чем платите |
|---|---|---|---|
| Агент без очереди | Короткие редкие действия | Минимум кода и инфраструктуры | Нет полноценного контроля повторов и зависших задач |
| Очередь в базе | Заказы, синхронизация, массовая обработка в одном проекте | Состояния, повторы, журнал и единое хранилище | Дополнительные запросы и конкуренция за ресурсы базы |
| Внешний брокер | Большой поток событий и несколько workers | Масштабирование и изоляция фоновой нагрузки | Отдельная инфраструктура и сложнее отладка |
Как выбрать вариант на практике
Начните не с количества строк, а с времени выполнения одного задания и последствий повтора. Если операция занимает доли секунды, запускается несколько раз в час и может безопасно повторяться, обычного агента достаточно. Если у задачи есть статус, внешний вызов или риск частичного выполнения, добавляйте очередь.
- Посчитайте поток. Запишите, сколько заданий появляется за минуту и сколько может обработать один worker. Оценка должна включать пики, например массовую загрузку товаров или рассылку после акции.
- Определите допустимую задержку. Если заказ должен уйти во внешнюю систему за секунды, запуск агента по расписанию может быть слишком медленным. Если допустимы минуты, отдельный брокер может оказаться лишним.
- Опишите повтор. Разделите ошибки на временные, постоянные и неизвестные. Таймаут внешнего API стоит повторить, а ошибку валидации данных — сохранить для ручного исправления.
- Сделайте операцию идемпотентной. Перед повтором проверьте, не был ли результат уже создан. Для внешнего API используйте его ключ идемпотентности, если такая возможность предусмотрена документацией.
- Добавьте наблюдаемость. Храните возраст самого старого задания, число ошибок, длительность обработки и количество повторов. Без этих метрик очередь может перестать работать задолго до того, как это заметит владелец сайта.
Что чаще всего ломается
Агент запускается на хите
Если сайт посещают редко, задания копятся. Если посещаемость высокая, фоновые операции начинают увеличивать время ответа. Для важных задач переводите агентов на cron-режим и проверяйте фактическое расписание, а не только флаг активности в административной части.
Один запуск обрабатывает всё
Агент, который пытается выгрузить тысячи товаров за один проход, упирается в лимит памяти или времени. Обрабатывайте ограниченную порцию и сохраняйте курсор: идентификатор последней записи, страницу или время следующей выборки.
Задание отмечают выполненным слишком рано
Если статус done записывается до успешного ответа внешней системы, сбой между двумя действиями приведёт к потере задания. Сначала подтвердите результат, затем меняйте статус. Для длинной операции используйте lease: временную отметку захвата, после истечения которой задачу можно вернуть в работу.
Повтор создаёт дубликаты
Одна и та же задача может быть повторена после таймаута, даже если внешний сервис успел её принять. Храните внешний идентификатор операции или собственный уникальный ключ, а повторную отправку делайте безопасной.
Где подход ломается
Очередь в базе не решает проблему, если worker не умеет восстанавливаться после падения. Статус processing без времени захвата навсегда оставит задачу зависшей. Внешний брокер тоже не гарантирует бизнес-результат: сообщение может быть доставлено, но обработчик упадёт после записи в Битрикс и до подтверждения доставки.
Не смешивайте в одном агенте несколько независимых процессов. Импорт каталога, отправка уведомлений и пересчёт цен должны иметь разные типы заданий, лимиты повторов и метрики. Иначе быстрый поток будет ждать медленный, а ошибка одной интеграции станет причиной задержки всех остальных.
Что делать дальше
Если сейчас у вас несколько простых агентов, соберите их длительность и частоту запусков за сутки. Всё, что выполняется долго, обращается к внешнему API или должно гарантированно завершиться, перенесите в очередь с явными статусами и повтором. После этого смотрите не только на количество ошибок, но и на возраст самого старого задания, среднее время обработки и долю повторных попыток. Внешний брокер имеет смысл добавлять тогда, когда очередь в базе уже стала измеримым ограничением, а не просто потому, что он выглядит современнее.
Риелтор и ипотечный брокер: Сравнение льготных ипотек, приёмка квартиры, проверка ДДУ.
Спросить за 15 ₽Источники: CAgent::AddAgent — документация API 1С-Битрикс, Документация разработчика 1С-Битрикс
Частые вопросы
Можно ли оставить все фоновые задачи на агентах Битрикс?
Что выбрать для синхронизации заказов с внешней системой?
Что произойдёт, если агент не успеет обработать задачу?
Нужно ли ставить RabbitMQ для нескольких тысяч заданий в день?
Как не отправить один заказ дважды после таймаута?
Подойдёт ли этот подход для другой версии Битрикс или PHP?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.