Налаштування відкладених функцій (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







