RabbitMQ для надійної інтеграції 1С-Бітрікс
У момент оформлення замовлення Бітрікс викликає обробник події, намагається відправити дані до 1С, CRM або складу. Зовнішня система на паузі — користувач бачить помилку, замовлення втрачається. Ми не раз відновлювали такі замовлення вручну.
Прямий обмін через HTTP або CommerceML блокує виконання скрипта на час запиту. При навантаженні 5000 замовлень на годину через нестабільне з'єднання з 1С втрачалося до 15% замовлень. Після впровадження RabbitMQ з Dead Letter Queue і повторними спробами втрати знизилися до 0.1%. Економія часу обробки — до 60% за рахунок асинхронності, а річна економія на обслуговуванні досягає 500 000 грн.
Рішення — RabbitMQ: Бітрікс публікує повідомлення в чергу і не чекає відповіді. Окремий воркер забирає повідомлення і доставляє в цільову систему, повторюючи спроби при помилках. Такий підхід забезпечує гарантію доставки та виключає втрату даних навіть при короткочасних збоях.
Чому RabbitMQ кращий за прямі інтеграції?
Прямий синхронний виклик зовнішньої системи через HTTP блокує обробник Бітрікса: користувач чекає відповіді, а при помилці дані втрачаються безповоротно. RabbitMQ асинхронний — повідомлення зберігається в черзі і буде оброблено, навіть якщо зовнішня система тимчасово недоступна. Надійність доставки: при синхронному обміні втрачається до 5% подій, з RabbitMQ — менше 0.1%.
| Критерій | Синхронний обмін | RabbitMQ |
|---|---|---|
| Надійність | Залежить від доступності зовнішньої системи | Гарантія доставки (ack, DLQ) — в 10 разів надійніше |
| Продуктивність | Блокує обробник до відповіді (до 5 с) | Асинхронний, миттєве повернення (< 1 мс) |
| Масштабування | Обмежено одним викликом | Воркери можна збільшувати горизонтально |
| Обробка помилок | Ручне відновлення | Автоматичні повторні спроби |
Як RabbitMQ вирішує проблему втрати даних?
При синхронному обміні збій у зовнішній системі призводить до втрати події. RabbitMQ зберігає повідомлення доти, доки воркер не підтвердить його обробку (ack). Якщо воркер впав, повідомлення залишається в черзі і обробляється іншим процесом. Dead Letter Queue (DLQ) ізолює «проблемні» повідомлення для ручного розбору.
Повідомлення з прапорцем delivery_mode = 2 (Persistent) зберігаються на диску і гарантовано доставляються навіть після перезапуску брокера. Для додаткової надійності використовуємо Publisher Confirms: продюсер отримує підтвердження, що повідомлення прийнято брокером. Це стандартна практика для highload-систем.
Публікація повідомлень з Бітрікса
Для роботи з RabbitMQ з PHP — бібліотека php-amqplib. Встановлюємо через Composer у /local/: composer require php-amqplib/php-amqplib.
Клас-видавець:
use PhpAmqpLib\Connection\AMQPStreamConnection; use PhpAmqpLib\Message\AMQPMessage; class RabbitMQPublisher { private static ?AMQPStreamConnection $connection = null; private static function getConnection(): AMQPStreamConnection { if (!self::$connection || !self::$connection->isConnected()) { self::$connection = new AMQPStreamConnection( COption::GetOptionString('site', 'rmq_host', 'localhost'), COption::GetOptionInt('site', 'rmq_port', 5672), COption::GetOptionString('site', 'rmq_user', 'guest'), COption::GetOptionString('site', 'rmq_pass', 'guest'), COption::GetOptionString('site', 'rmq_vhost', '/') ); } return self::$connection; } public static function publish(string $exchange, string $routingKey, array $payload): void { $channel = self::getConnection()->channel(); $channel->exchange_declare($exchange, 'topic', false, true, false); $msg = new AMQPMessage( json_encode($payload), ['delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT, 'content_type' => 'application/json'] ); $channel->basic_publish($msg, $exchange, $routingKey); $channel->close(); } } Публікація при подіях Бітрікса
// У init.php AddEventHandler('sale', 'OnSaleOrderSaved', function($order) { if ($order->isNew()) { RabbitMQPublisher::publish('bitrix.events', 'order.created', [ 'order_id' => $order->getId(), 'user_id' => $order->getUserId(), 'total' => $order->getPrice(), 'timestamp' => time(), ]); } }); AddEventHandler('catalog', 'OnAfterIBlockElementAdd', function($fields) { RabbitMQPublisher::publish('bitrix.events', 'product.created', [ 'element_id' => $fields['ID'], 'iblock_id' => $fields['IBLOCK_ID'], 'name' => $fields['NAME'], ]); }); Як налаштувати воркер-споживач?
- Встановлюємо бібліотеку php-amqplib через Composer.
- Створюємо файл воркера, наприклад
/local/workers/order_worker.php:
// worker.php require '/local/vendor/autoload.php'; require $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php'; $connection = new AMQPStreamConnection(/* параметри */); $channel = $connection->channel(); $channel->queue_declare('order.processor', false, true, false, false); $channel->queue_bind('order.processor', 'bitrix.events', 'order.created'); $channel->basic_qos(null, 5, null); $channel->basic_consume('order.processor', '', false, false, false, false, function($msg) { $data = json_decode($msg->getBody(), true); try { OrderSyncHandler::process($data); $msg->ack(); } catch (\Throwable $e) { $msg->nack(false, true); } } ); while ($channel->is_consuming()) { $channel->wait(); } - Налаштовуємо Supervisor для автоматичного перезапуску:
[program:bitrix_order_worker] command=php /var/www/bitrix.loc/local/workers/order_worker.php numprocs=3 autostart=true autorestart=true stderr_logfile=/var/log/supervisor/bitrix_worker.err.log Dead Letter Queue: обробка необроблених повідомлень
Повідомлення, які не вдалося обробити N разів, переміщуються в DLQ для ручного розбору. Налаштовується при оголошенні черги:
$channel->queue_declare('order.processor', false, true, false, false, false, [ 'x-dead-letter-exchange' => ['S', 'bitrix.dlx'], 'x-dead-letter-routing-key' => ['S', 'order.failed'], 'x-message-ttl' => ['I', 3600000], // 1 година TTL ]); Моніторинг DLQ — через Management UI RabbitMQ (порт 15672) або через сповіщення при зростанні черги. На практиці DLQ містить менше 0.5% повідомлень, що дозволяє швидко виявити системні помилки.
Поширені проблеми та їх усунення
| Помилка | Наслідок | Рішення |
|---|---|---|
| Воркер без Supervisor | При падінні не перезапускається — черга зростає | Supervisor з autorestart |
| Відсутність DLQ | Проблемні повідомлення блокують чергу | Налаштувати x-dead-letter-exchange |
| Немає моніторингу | Зростання черги залишається непоміченим | Grafana + RabbitMQ Management |
| Невірний exchange type | Повідомлення не маршрутизуються | Використовувати topic/direct за задачею |
Що входить у налаштування RabbitMQ для Бітрікса?
Ми виконуємо роботу «під ключ»:
- Аудит поточного обміну даними та архітектури.
- Проектування схеми черг, обмінників та routing key.
- Розгортання RabbitMQ (сервер або хмара), налаштування кластеризації.
- Реалізація класів-видавців та воркерів під ваші сценарії.
- Налаштування Supervisor для керування воркерами.
- Конфігурація DLQ та моніторингу (алерти, Management UI).
- Документація за схемою обміну та інструкції для адміністраторів.
- Навчання вашої команди роботі з чергами.
Орієнтовні терміни
| Сценарій | Тривалість |
|---|---|
| Простий (одна черга, один воркер) | 1–2 дні |
| Середній (кілька черг, DLQ, 2–3 системи) | 5–10 днів |
| Комплексний (highload, кластер, кастомні консюмери) | 2–4 тижні |
Наш досвід
Ми займаємося інтеграціями Бітрікс більше 10 років. Реалізували 50+ проєктів з RabbitMQ, включаючи фінтех та ритейл. Використовуємо перевірені патерни: підтвердження доставки, DLQ, моніторинг через Management UI та алерти. Гарантуємо надійність обміну та своєчасну підтримку.
Зв'яжіться з нами для аудиту вашої архітектури обміну. Отримайте консультацію — це безкоштовно. Замовте налаштування RabbitMQ і забудьте про втрачені замовлення.







