Настройка отложенных функций (deferred functions) 1С-Битрикс
Пользователь нажимает «Оформить заказ» — и ждёт 4 секунды, пока сервер отправляет письмо, считает бонусы, дёргает API доставки и пишет лог. Всё это происходит синхронно в обработчиках события OnSaleOrderBeforeSaved. Deferred functions позволяют вынести тяжёлые операции из основного потока: ответ пользователю уходит сразу, а фоновые задачи выполняются после отправки HTTP-ответа.
Механизм работы
Начиная с PHP 8.1, ядро Битрикс поддерживает register_shutdown_function и собственный механизм отложенного выполнения через Bitrix\Main\Application::getInstance()->addBackgroundJob(). Суть: функция регистрируется в очередь, которая выполняется после fastcgi_finish_request() (для PHP-FPM) или после отправки ответа (для Apache mod_php через register_shutdown_function).
use Bitrix\Main\Application;
Application::getInstance()->addBackgroundJob(function () {
// Этот код выполнится ПОСЛЕ отправки ответа клиенту
\Bitrix\Main\Mail\Event::send([...]);
// Запись в лог, вызов API, пересчёт данных
});
Критический нюанс: addBackgroundJob работает только при наличии fastcgi_finish_request(). Если PHP запущен как модуль Apache (mod_php) — функция выполнится до отправки ответа, потому что register_shutdown_function не освобождает соединение. Проверяйте: function_exists('fastcgi_finish_request').
Когда использовать
- Отправка email/SMS после оформления заказа — задержка 200–500 мс на каждое письмо
- Логирование — запись в файл или внешний сервис (ELK, Sentry)
- Инвалидация кеша — пересборка тегированного кеша после обновления каталога
- Вызовы внешних API — уведомление CRM, обновление складского сервиса
- Обновление поисковых индексов — переиндексация элемента после изменения
Ограничения
- Нет гарантии выполнения: если процесс PHP упадёт (OOM, kill) — задача потеряется. Для критичных операций (оплата, создание документов) используйте очередь задач, а не deferred functions.
- Нет повторных попыток: если API вернул ошибку — обработки retry нет.
- Нет мониторинга: нельзя узнать, сколько задач в очереди и сколько выполнилось.
- Порядок выполнения — FIFO в рамках одного запроса, но между запросами — не гарантирован.
Настройка PHP-FPM
Для корректной работы deferred functions на PHP-FPM проверьте:
-
request_terminate_timeoutв пуле FPM — должен быть достаточным для завершения фоновых задач (по умолчанию — 0, неограниченно). Если задан 30 секунд, а фоновая задача выполняется 40 — процесс будет убит. -
pm.max_children— каждый запрос с фоновыми задачами удерживает воркер дольше. При высоком трафике это может привести к исчерпанию пула.
Что настраиваем
- Проверка совместимости серверного окружения (PHP-FPM,
fastcgi_finish_request) - Вынос тяжёлых обработчиков событий в
addBackgroundJob - Настройка
request_terminate_timeoutв PHP-FPM - Мониторинг: логирование времени выполнения фоновых задач
- Тестирование: замер времени ответа до и после переноса операций в deferred







