Архитектура
Интеграции Битрикс24: очередь, повторы и защита от дублирования
Что предусмотреть в обмене данными, если внешний запрос завершился таймаутом, ответ потерялся или одно событие пришло несколько раз.

Таймаут не доказывает, что внешняя операция не выполнилась. Сервис мог сохранить данные, а ответ — потеряться по пути. Если просто повторить создание, появится дубль. Поэтому надёжность обмена начинается с правил идентификации и восстановления, а не с бесконечного цикла повторов.
Ниже — проектный подход для интеграций корпоративных систем. Это не описание встроенной гарантии Битрикс24: конкретная реализация зависит от API обеих сторон.
Сначала определить владельца данных
Для каждой сущности нужно знать, где находится источник истины и какие поля разрешено менять другой стороне. Двусторонний обмен без этого правила быстро превращается в спор двух автоматизаций, перезаписывающих данные друг друга.
Полезно вести соответствие идентификаторов: источник, внешний ID и локальный ID. Для операции дополнительно нужен устойчивый ключ, сохраняющийся при повторной доставке. Случайный новый ключ при каждой попытке не помогает распознать повтор.
Что означает идемпотентность
Идемпотентная обработка одной операции при повторении не создаёт дополнительного нежелательного эффекта. Например, повторное событие о регистрации заявки должно ссылаться на уже созданную задачу, а не создавать следующую.
Проверка «записи пока нет» перед созданием недостаточна при параллельной работе: два обработчика могут проверить отсутствие одновременно. Нужна согласованная защита на уровне хранения или механизм идемпотентности принимающего API.
Если внешняя система не поддерживает ключ операции, проектируют другой способ сверки. Иногда требуется поиск по согласованному внешнему идентификатору; иногда — ручной разбор неопределённого результата. Обещать универсальную доставку «ровно один раз» между произвольными системами нельзя.
Зачем нужна очередь
Очередь отделяет пользовательское действие от попытки обмена и хранит его состояние. Важно, чтобы она переживала перезапуск процесса и позволяла понять, что осталось невыполненным.
Пример полей записи: идентификатор операции, тип события, ссылка на сущность, версия данных, состояние, число попыток, время следующей попытки и код последней ошибки. Состав данных зависит от требований к восстановлению; секреты доступа и избыточные персональные данные в запись не включают.
| Состояние | Значение |
|---|---|
| Ожидает | Операция принята для обработки |
| Выполняется | Попытку забрал конкретный обработчик |
| Требует повтора | Подтверждена временная ошибка |
| Выполнена | Получен и сохранён ожидаемый результат |
| Требует разбора | Автоматический повтор небезопасен или исчерпан |
Захват записи должен исключать одновременное выполнение двумя обработчиками. Нужен также механизм восстановления записи, если обработчик завершился аварийно. Повторный захват безопасен только вместе с защитой от повторного эффекта.
Разделить типы ошибок
При временной недоступности можно назначить следующую попытку с растущей задержкой и небольшим случайным разбросом. Это уменьшает вероятность одновременного повторного штурма сервиса всеми обработчиками.
Неверный формат данных, отсутствие прав и бизнес-конфликт требуют исправления причины. Их бессмысленно повторять без изменений. Для таймаута после отправки результата может быть недостаточно, чтобы сразу решить, какой вариант произошёл: отказ или успешная операция без ответа.
Для REST Битрикс24 нужно учитывать документированные ошибки и лимиты. Ограничения облака нельзя автоматически переносить на коробочную установку: там существенны настройки сервера и модуля. Числовые значения следует сверять с актуальной документацией и конкретным окружением.
Согласованность и порядок событий
Если изменение в базе сохранено, а запись в очередь потеряна, обмен не начнётся. Когда обе записи находятся в одной транзакционной базе, можно рассмотреть запись задания вместе с изменением данных в одной транзакции — подход outbox. Для разных хранилищ нужна отдельная стратегия восстановления и сверки.
Ещё один вопрос — запоздавшее событие. Старое изменение не должно перезаписывать более новое только потому, что доставлено позднее. Для этого используют согласованную версию сущности или другой порядок, который поддерживают обе стороны.
Минимальные сценарии проверки
- Дважды доставить одну операцию: нежелательного дубля нет.
- Запустить двух обработчиков: они не выполняют одну запись одновременно.
- Оборвать ответ после внешнего сохранения: повтор не создаёт второй объект.
- Перезапустить обработчик: незавершённое задание обнаруживается и восстанавливается.
- Доставить старое изменение после нового: актуальное состояние сохраняется.
- Передать некорректные данные: задание получает понятную ошибку и не крутится бесконечно.
Наблюдаемость дополняет эти проверки: нужны возраст старейшей задачи, число ошибок, состояния очереди и связь записи журнала с конкретной операцией. Само наличие запущенного обработчика не подтверждает исправность обмена.