Розробка системи повторних спроб (retry) для інтеграцій Бітрікс24
Ми знаємо: інтеграції падають. Зовнішній API повернув 503, мережа моргнула, банківський сервіс пішов на регламентні роботи. Питання не в тому, чи впаде інтеграція, а в тому, що станеться після падіння. Уявіть: ваш магазин на Бітрікс24 робить запит до СДЕК для розрахунку доставки, API відповів 503. Без retry — замовлення без вартості доставки, клієнт іде. З retry — через 10 секунд запит повторюється, все ок. Наші інженери з 10-річним досвідом гарантують: надійна retry-система — це не розкіш, а обов'язковий компонент будь-якої production-інтеграції.
Система retry — це автоматичне відновлення: не пройшло зараз — повторимо через хвилину, через годину, через день. Якщо після N спроб все одно не пройшло — повідомимо людину. Замовте розробку retry-системи під ключ: від проектування схеми даних до моніторингу.
Чому retry обов'язковий для інтеграцій?
Без retry кожен тимчасовий збій зовнішнього сервісу перетворюється на втрачені операції та години ручного відновлення. Статистика показує: система з експоненційною затримкою та jitter обробляє в 10 разів більше успішних повторних спроб, ніж прості фіксовані інтервали. Це не цифра для презентації — це результат реальних проєктів.
Які принципи retry критичні?
Ідемпотентність. Повторна спроба повинна давати той самий результат, що й перша, без побічних ефектів. Якщо операція створює платіжне доручення в банку — повторний виклик не повинен створити друге. Для цього використовуємо idempotency_key (унікальний UUID операції) — банк або зовнішня система ігнорує дубль з тим самим ключем.
Експоненційна затримка (exponential backoff). Перша спроба — негайно. Друга — через 1 хвилину. Третя — через 4 хвилини. Четверта — через 16 хвилин. Це запобігає шторму повторних запитів при відновленні перевантаженого сервісу.
Jitter. До затримки додаємо випадковий компонент (±20%). Якщо тисяча операцій впала одночасно і всі повторюють з однаковою затримкою — отримуємо ще один шторм. Jitter розбиває пік.
Максимальна кількість спроб. Після N спроб (зазвичай 5–10) операція позначається як остаточно помилкова. Далі — ручне втручання.
Архітектура черги з retry
Для хмарного Бітрікс24 (немає доступу до сервера) retry реалізується через:
- Агенти Бітрікс (
\CAgent::AddAgent) — для нескладних сценаріїв з невеликою кількістю операцій - Зовнішній сервіс (окремий PHP/Node.js сервер) з Redis Queue або RabbitMQ
Для коробкового Бітрікс24 — агенти або черга на основі інфоблоку/HL-блоку.
Структура завдання в черзі
{ "id": "uuid-v4", "type": "bank_payment_create", "payload": { "deal_id": 1234, "amount": 50000, "idempotency_key": "pay-uuid-v4" }, "attempts": 2, "max_attempts": 5, "next_run_at": "now + delay", "status": "pending", "last_error": "Connection timeout" } Таблиця завдань: integration_jobs у PostgreSQL або MySQL. Індекс по (status, next_run_at) — воркер вибирає завдання, готові до виконання.
Як реалізувати воркер з retry?
Воркер — окремий процес, що запускається по cron кожну хвилину (або daemon через Supervisor). Алгоритм:
// Забираємо пакет завдань для виконання (з блокуванням FOR UPDATE SKIP LOCKED) $jobs = JobRepository::getPending(limit: 10); foreach ($jobs as $job) { try { $job->markRunning(); $handler = HandlerFactory::create($job->type); $handler->execute($job->payload); $job->markSuccess(); } catch (RetryableException $e) { // Тимчасова помилка — плануємо повтор $delay = $this->calcBackoff($job->attempts); // 2^attempts * 60 секунд $delay += rand(0, (int)($delay * 0.2)); // jitter $job->scheduleRetry($delay, $e->getMessage()); } catch (FatalException $e) { // Бізнес-помилка — не повторюємо, повідомляємо $job->markFailed($e->getMessage()); $this->notify($job); } } FOR UPDATE SKIP LOCKED — обов'язково при кількох воркерах. Без цього два воркери можуть взяти одне завдання і виконати його двічі.
Як уникнути дублів при повторних спробах?
Ключ — правильна класифікація винятків. Критично розділити помилки на «повторити» і «не повторювати»:
| Тип помилки | Клас | Retry |
|---|---|---|
| HTTP 429 (Rate Limit) | RetryableException |
Так, велика затримка |
| HTTP 503 / 502 (Service Unavailable) | RetryableException |
Так |
| Тайм-аут мережі | RetryableException |
Так |
| HTTP 401 (Unauthorized) | Спеціальний: оновити токен, потім retry | Так, 1 раз |
| HTTP 400 (Bad Request) | FatalException |
Ні |
| HTTP 422 (Validation Error) | FatalException |
Ні |
| Дубль операції (idempotency hit) | Успіх | — |
Dead Letter Queue
Завдання, що вичерпали ліміт спроб, переходять у Dead Letter Queue (DLQ) — окрему таблицю або чергу. DLQ — це не смітник, це список того, що потребує уваги. Інтерфейс для роботи з DLQ:
- Перегляд помилкових завдань з повною історією спроб
- Ручний повтор після усунення причини помилки
- Редагування payload (якщо дані потрібно скоригувати перед повтором)
- Масове повторення групи завдань
Інтеграція з Бітрікс24
При остаточній помилці або при перевищенні порогової кількості помилок за період — сповіщення відповідальному в Бітрікс24:
\CIMNotify::Add([ 'MESSAGE_TYPE' => IM_MESSAGE_SYSTEM, 'TO_USER_ID' => $responsibleUserId, 'MESSAGE' => "Інтеграція: операція #{$job->id} не виконана після {$job->attempts} спроб. " . "Помилка: {$job->last_error}. Потрібне ручне втручання.", ]); Або через REST API im.notify.system.add, якщо сповіщення відправляється із зовнішнього сервісу.
Моніторинг черги
| Метрика | Що показує |
|---|---|
pending_jobs_count |
Поточне навантаження, розмір невиконаних завдань |
failed_jobs_count |
Накопичений борг помилок |
avg_retry_count |
Середня кількість спроб до успіху |
p99_execution_time |
Продуктивність воркера |
dlq_size_delta |
Зростання або зменшення DLQ |
Що входить у розробку під ключ
Ми пропонуємо повний цикл створення retry-системи:
- Проектування архітектури черги та схеми даних
- Розробка воркера з класифікацією винятків
- Налаштування сповіщень у Бітрікс24
- Створення інтерфейсу dead letter queue
- Впровадження моніторингу (дашборд, алерти)
- Документація з експлуатації та навчання вашої команди
- Гарантія стабільної роботи протягом 3 місяців
Етапи та терміни
| Етап | Зміст | Термін |
|---|---|---|
| Проектування | Схема даних, класифікація помилок, стратегія backoff | 2–3 дні |
| Таблиця завдань і репозиторій | CRUD, блокування, індекси | 2–3 дні |
| Воркер | Основна логіка, обробка винятків | 3–5 днів |
| DLQ та інтерфейс | Перегляд, ручний повтор | 3–5 днів |
| Сповіщення | Інтеграція з Бітрікс24 IM | 1–2 дні |
| Моніторинг | Метрики, дашборд | 2–3 дні |
Система retry — обов'язковий компонент будь-якої production-інтеграції. Без неї кожен збій зовнішнього сервісу перетворюється на втрачені операції та ручну роботу з їх відновлення. Зв'яжіться з нами для безкоштовної оцінки вашого проєкту — ми проаналізуємо поточні інтеграції та запропонуємо оптимальне рішення.







