Блог Горошко Андрея 1C-Битрикс,PHP,Разработка Background Jobs: Руководство разработчика

Background Jobs: Руководство разработчика

Эффективная интеграция и кастомизация функционала в Битрикс24 часто требует работы на уровне API. Сегодня мы подробно рассмотрим «Background Jobs: Руководство разработчика». Вы узнаете экспертные методики работы с background jobs и научитесь избегать типичных ошибок начинающих разработчиков.

—
title: Агенты и фоновые задачи
—

Агенты и фоновые задачи помогают выполнять PHP-код автоматически.

  • Агенты — запускают код по расписанию.
  • Фоновые задачи — после отправки ответа пользователю.

Отличия агентов от фоновых задач

ХарактеристикаАгентыФоновые задачи
ЗапускПри посещении сайта посетителями (на хитах) и по расписанию через cronСразу после ответа пользователю
Время выполненияМогут задерживатьсяПочти мгновенное
ПриоритетыНетЕсть
Подходит дляРегулярных задачРазовых тяжелых операций

Для сложных сценариев можно комбинировать оба подхода.

// Фоновая задача запускает агента для поэтапной обработки
$app->addBackgroundJob(function() {
    CAgent::AddAgent(
        "MyLongProcess::start();",
        "mymodule",
        "N",
        0
    );
});

Агенты

Агент — это запись в базе данных, которая содержит:

  • код для выполнения,
  • время следующего запуска,
  • интервал выполнения,
  • тип агента: периодический или непериодический.

Агенты выполняются в однопоточном режиме. Если агент работает дольше 10 минут, система блокирует его повторный запуск — это защита от дублирования. На другие агенты и процессы блокировка не влияет.

Типы агентов

  • Периодические. Запускаются в указанное время.

Время следующего запуска = время предыдущего запуска + интервал.

  • Непериодические. Запускаются через заданный интервал и только после успешного завершения предыдущего выполнения, что исключает накладки.

Время следующего запуска = время окончания работы + интервал.

Зарегистрировать агента

Для работы с агентами используйте методы класса CAgent.

  • Метод addAgent добавляет агент.
   CAgent::AddAgent(
       "MyFunction();",      // Имя функции для вызова
       "mymodule",           // Модуль. Передавайте пустое значение для функций в init.php
       "N",                  // Периодичность: "N" — непериодический, "Y" — периодический
       3600,                 // Интервал в секундах. Например, 3600 сек, то есть 1 час
       "",                   // Дата проверки в формате YYYY-MM-DD HH:MI:SS
       "Y",                  // Активность: "Y" — активен, "N" — неактивен
       "",                   // Дата следующего выполнения в формате YYYY-MM-DD HH:MI:SS
       100,                  // Сортировка. Чем меньше значение, тем выше приоритет
       false,                // ID пользователя. По умолчанию false, то есть для системных агентов
       true                  // Выдавать ошибку при дублировании агента
   );
  • Метод RemoveAgent удаляет агент.
   CAgent::RemoveAgent(
       "MyFunction();",      // Имя функции агента
       "mymodule",           // Модуль. Передавайте пустое значение для функций в init.php
       false                 // ID пользователя. По умолчанию false, то есть для системных агентов
   );

Создать агента через интерфейс

Агента можно добавить через административный раздел на странице Настройки > Настройки продукта > Агенты. Нажмите Добавить агента и заполните параметры, аналогичные регистрации через функцию addAgent.

![](./background-jobs.png){width=638px height=340px}

Запустить агента

  • На хитах. Агент срабатывает, когда посетитель заходит на страницу. Точность запуска зависит от посещаемости сайта. Система обрабатывает агентов по одному и при большом трафике агенты на хитах создают нагрузку на сайт.
  • Через cron. Агент запускается точно по расписанию и не зависит от посещаемости. Это снижает нагрузку на сайт.

Частично перевести запуск на cron

Агенты можно перевести на cron частично. Система продолжит запускать агенты при посещениях, а cron будет запускать только часть агентов.

1. Откройте страницу Настройки > Инструменты > Командная PHP-строка. Выполните код:

   // Включить частичный перевод агентов на cron
   COption::SetOptionString(
       "main",                 // Модуль main
       "agents_use_crontab",   // Настройка использования cron
       "Y"                     // Y — разрешить, N — запретить
   );
   
   // Проверить текущее значение настройки
   echo COption::GetOptionString("main", "agents_use_crontab", "N"); // вернет значение Y

После выполнения кода система будет запускать на хитах только периодические агенты.

2. Добавьте задание cron на сервере:

   # Выполнять каждые 10 минут от имени пользователя
   */10 * * * * bitrix /usr/bin/php -f /home/bitrix/www/bitrix/modules/main/tools/cron_events.php

Часть пути /home/bitrix/www/ замените на путь к вашему сайту.

Полностью перевести запуск на cron

Агенты не будут зависеть от посещаемости сайта и сработают точно по расписанию.

1. Откройте страницу Настройки > Инструменты > Командная PHP-строка. Выполните код, который полностью отключит запуск агентов.

   COption::SetOptionString(
       "main",                 // Модуль main
       "agents_use_crontab",   // Настройка использования cron
   	"N"                     // Y — разрешить, N — запретить
   ); 
   echo COption::GetOptionString("main", "agents_use_crontab", "N"); // Выведет значение N — cron отключен для агентов
   
   COption::SetOptionString(
       "main",                 // Модуль main
       "check_agents",         // Настройка проверки агентов
   	"N"                     // Y — разрешить, N — запретить
   );
   echo COption::GetOptionString("main", "check_agents", "Y"); // Выведет значение N — значит автоматическая проверка агентов отключена

2. Удалите в файле /bitrix/php_interface/dbconn.php константы BX_CRONTAB_SUPPORT и BX_CRONTAB.

   define("BX_CRONTAB_SUPPORT", true);
   define("BX_CRONTAB", true);

3. Добавьте в файл строчку:

   if (!(defined("CHK_EVENT") && CHK_EVENT===true)) {
       define("BX_CRONTAB_SUPPORT", true); // Разрешаем работу через cron
       // При этом обычные хиты не будут запускать агентов
   }

4. Создайте файл /bitrix/php_interface/cron_events.php, который будет проверять агенты и рассылки системных сообщений. Разместите в нем код:

   <?php
   // Устанавливаем корневую директорию
   $_SERVER["DOCUMENT_ROOT"] = realpath(dirname(__FILE__)."/../..");
   
   // Отключаем проверки для ускорения работы
   define("NO_KEEP_STATISTIC", true);       // Не вести статистику
   define("NOT_CHECK_PERMISSIONS", true);   // Не проверять права
   define('BX_NO_ACCELERATOR_RESET', true); // Не сбрасывать акселератор
   
   // Указываем, что это вызов через cron
   define('CHK_EVENT', true);
   
   // Разрешаем обработку после эпилога, для некоторых модулей
   define('BX_WITH_ON_AFTER_EPILOG', true);
   
   // Подключаем ядро Bitrix
   require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");
   
   // Увеличиваем время выполнения
   @set_time_limit(0);                     // Без ограничения времени
   @ignore_user_abort(true);               // Продолжать при обрыве связи
   
   // 1. Проверяем и запускаем агентов
   CAgent::CheckAgents();
   
   // Константы, которые обычно определяются в dbconn.php
   define("BX_CRONTAB_SUPPORT", true);      // Поддержка cron
   define("BX_CRONTAB", true);              // Пометка текущего выполнения как cron
   
   // 2. Обрабатываем почтовые события (если модуль установлен)
   if(CModule::IncludeModule('sender')) {
       \Bitrix\Sender\MailingManager::checkPeriod(false);
       \Bitrix\Sender\MailingManager::checkSend();
   }
   
   // Завершаем работу
   require($_SERVER['DOCUMENT_ROOT']."/bitrix/modules/main/tools/backup.php");
   CMain::FinalActions();
  • Скрипт устанавливает CHK_EVENT=true перед подключением ядра.
  • Система определяет, что это cron, и разрешает работу агентов.
  • Функция CheckAgents() запускает всех агентов, которые должны выполниться.

5. Добавьте задание cron на сервере:

   # Выполнять каждые 10 минут от имени пользователя
   */10 * * * * bitrix /usr/bin/php -f /home/bitrix/www/bitrix/modules/main/tools/cron_events.php

Часть пути /home/bitrix/www/ замените на путь к вашему сайту.

Вернуть запуск агентов на хитах

1. В таблице b_option удалите записи NAME = agents_use_crontab и NAME = check_agents.

2. Очистите управляемый кеш в административном разделе.

3. Удалите изменения из /bitrix/php_interface/dbconn.php.

Функции агентов

Функция агента — это PHP-код, который выполняется при запуске агента. Функция должна вернуть строку с кодом для следующего запуска. Чтобы остановить агента — пустую строку.

function TestAgent() {
    mail('mail@gmail.com', 'Тест агента', 'Агент работает'); // код функции
    return "TestAgent();"; // Для повторного запуска
	// Для остановки агента передайте пустой return "";
}

Где размещать функции

  • В модуле. Укажите модуль при регистрации агента. Функция становится доступной после подключения модуля, то есть файла /bitrix/modules/[MODULE_ID]/include.php.
   CAgent::AddAgent("Function();", "module_id");
  • Без модуля. Разместите функцию в файле /bitrix/php_interface/init.php. Модуль в параметрах регистрации указывать не нужно.
   CAgent::AddAgent("Function();");

Примеры агентов

1. Очистить статистику.

   CAgent::AddAgent(
   	"CStatistic::CleanUpStatistics_2();", // имя функции
   	"statistic",                          // идентификатор модуля
   	"N",                                  // агент не критичен к кол-ву запусков
   	86400,                                // интервал запуска — 1 сутки
   	"07.04.2025 20:03:26",                // дата первой проверки на запуск
   	"Y",                                  // агент активен
   	"07.04.2025 20:03:26",                // дата первого запуска
   	30
   );

2. Ограничить число запусков агента.

   // Агент завершится после 5 запусков
   class CMyModule {
       public static function AgentLimited($count = 1) {
           if ($count >= 5) return ""; // Остановка агента
           return "CMyModule::AgentLimited(".($count+1).");"; // Следующий запуск
       }
   }
   
   // Регистрируем агент
   CAgent::AddAgent(
       "CMyModule::AgentLimited();",
       "my_module",
       "Y",
       86400
   );

3. Обновить курс валют. Курс валюты не должен зависеть от хитов, поэтому агента нужно запускать через cron.

   function AgentCurrencyUpdate() {
       // Проверка подключения модуля валют
       if (!CModule::IncludeModule('currency')) {
           return "AgentCurrencyUpdate();"; // Повторить попытку
       }
   
       // Запрос к API ЦБ (возвращает курс рубля к валютам)
       $json = file_get_contents('https://api.exchangerate.host/latest?base=RUB');
       if (!$json) {
           return "AgentCurrencyUpdate();"; // Ошибка запроса — повторить
       }
   
       // Декодирование JSON и проверка данных
       $data = json_decode($json, true);
       $rates = $data['rates'] ?? [];
       if (empty($rates)) {
           return "AgentCurrencyUpdate();"; // Нет данных — повторить
       }
   
       // Обновление курсов в базе
       foreach (['USD', 'EUR'] as $currency) {
           // Конвертируем курс (1 USD = X RUB, 1 RUB = 1/X USD)
           $convertedRate = 1 / ($rates[$currency] ?? 1);
           
           CCurrencyRates::Add([
               'CURRENCY' => $currency,    // Код валюты
               'DATE_RATE' => date('Y-m-d'), // Текущая дата
               'RATE' => $convertedRate,   // Рассчитанный курс
               'RATE_CNT' => 1             // Номинал, 1 единица валюты
           ]);
       }
   
       // Запланировать следующий запуск
       return "AgentCurrencyUpdate();";
   }

Ограничения агентов

1. Нет доступа к переменной $USER.

2. Нельзя использовать авторизацию методом Authorize.

3. Нет константы SITE_ID.

4. Нельзя определить заранее язык на многоязычных сайтах.

Фоновые задачи

Фоновые задачи выполняются сразу после отправки ответа пользователю в рамках одного HTTP-запроса. Они не замедляют работу сайта, но не гарантируют выполнение. Фоновая задача может не выполниться при аварийном завершении скрипта.

1. Задача ставится в очередь.

2. После отправки контента пользователю система выполняет задачу.

3. Во время выполнения задачи ответ сервера не блокируется.

Фоновые задачи можно использовать:

  • чтобы отправить почту после регистрации,
  • сгенерировать документ в формате PDF,
  • выполнить синхронизацию с внешними API,
  • обработать загруженный файл,
  • массово обновить данные.

Добавить фоновую задачу

Метод addBackgroundJob добавляет фоновую задачу.

\Bitrix\Main\Application::addBackgroundJob(
    $job,
    $args,
    $priority
)
  • $job — вызываемая функция или метод. В качестве значения можно передать вызываемую функцию (callable) "myFunction" или массив для методов ["MyClass", "method"].
  • $args — массив аргументов для вызова функции или метода.
  • $priority — приоритет выполнения. Возможные значения:
   \Bitrix\Main\Application::JOB_PRIORITY_NORMAL // 100, используется по умолчанию
   \Bitrix\Main\Application::JOB_PRIORITY_LOW    // 50

Примеры фоновых задач

1. Базовый пример с функцией отправки письма.

   $app = \Bitrix\Main\Application::getInstance();
   $app->addBackgroundJob(
       [EmailService::class, 'sendWelcome'],
       ['user@example.com', 'Добро пожаловать!'],
   );
   
   function sendWelcomeEmail($email, $message) {
       mail($email, 'Уведомление', $message);
   }

2. Пример фоновой задачи с низким приоритетом. Функция обрабатывает загруженный файл.

   // Подготовка файла перед фоновой задачей
   $tmpFilePath = \Bitrix\Main\Application::getDocumentRoot().'/upload/tmp/'.uniqid('file_');
   
   // Перемещаем загруженный файл в постоянное хранилище
   if (!move_uploaded_file($_FILES['big_file']['tmp_name'], $tmpFilePath)) {
       throw new \Exception('File upload failed');
   }
   
   // Регистрируем фоновую задачу
   $app = \Bitrix\Main\Application::getInstance();
   $app->addBackgroundJob(
       // Используем callable-синтаксис для вызова функции, которая обработает файл
       [FileProcessor::class, 'processLargeFile'],
       // Передаем файл
       [
           'path' => $tmpFilePath,
           'original_name' => $_FILES['big_file']['name']
       ],
       // Устанавливаем низкий приоритет
       \Bitrix\Main\Application::JOB_PRIORITY_LOW
   );

💡 Экспертное мнение и рекомендации

Ключевые выводы по теме «Background Jobs: Руководство разработчика»:

Использование современных стандартов D7 при работе с background jobs позволяет писать чистый, масштабируемый и безопасный код. Не забывайте обрабатывать исключения (try/catch) и проверять права доступа текущего пользователя перед выполнением критических операций.

Похожая задача в бизнесе?

Помогу автоматизировать процессы и внедрить ИИ

Меня зовут Андрей Горошко. Я Full-stack разработчик и эксперт по 1С-Битрикс. Настраиваю CRM Битрикс24, разрабатываю защищенные API и создаю умных ИИ-агентов для автоматизации рутины.

Related Post

Обновить состав списка обзвона crm.calllist.updateОбновить состав списка обзвона crm.calllist.update

Каждый PHP-разработчик, работающий с экосистемой Bitrix Framework, должен глубоко понимать работу её ключевых компонентов. В этой статье мы проведем подробный аудит темы «Обновить состав списка обзвона crm.calllist.update», проанализируем лучшие практики

Обновить тип цены catalog.priceType.updateОбновить тип цены catalog.priceType.update

Эффективная интеграция и кастомизация функционала в Битрикс24 часто требует работы на уровне API. Сегодня мы подробно рассмотрим «Обновить тип цены catalog.priceType.update». Вы узнаете экспертные методики работы с catalog.priceType.update и научитесь

Как использовать метод SDK bizproc.robot.update в Битрикс24Как использовать метод SDK bizproc.robot.update в Битрикс24

Каждый PHP-разработчик, работающий с экосистемой Bitrix Framework, должен глубоко понимать работу её ключевых компонентов. В этой статье мы проведем подробный аудит темы «Как использовать метод SDK bizproc.robot.update в Битрикс24», проанализируем