Архитектура модулей интеграции
Платформа DataHUB сама по себе не делает обмен — она предоставляет API, к которому подключаются клиентские системы. На стороне каждой клиентской системы должен быть свой модуль интеграции (адаптер): код, который умеет формировать сообщения в формате шины, отправлять их через REST API, забирать входящие, обрабатывать их и подтверждать.
Готовые модули интеграции описаны в разделе Модули интеграции. Эта статья описывает общую модель клиентского модуля, по которой проектируется любой адаптер, независимо от языка и платформы.
Что делает модуль интеграции
Любой модуль интеграции, чтобы корректно работать с шиной, должен реализовать шесть обязательных блоков функциональности:
- Локальная очередь исходящих сообщений — буфер, в который кладутся сообщения, ожидающие отправки.
- Локальный пул входящих сообщений — таблица в БД получателя, куда складываются принятые сообщения до момента прикладной обработки.
- Транспорт — клиент REST API DataHUB: авторизация, отправка, получение, подтверждение.
- Обработчики исходящих — код, который превращает события учётной системы (создан документ, изменён справочник) в сообщения.
- Обработчики входящих — код, который применяет сообщения из локального пула к бизнес-данным учётной системы.
- Регламентные задания — фоновая работа: отправка накопленного, приём новых, отложенная обработка, переотправка не подтверждённых.
Этот набор — необходимый и почти достаточный. Дополнительные элементы (UI настройки, мониторинг, логирование, защита от дубликатов) — практически всегда добавляются вокруг ядра, но именно эти шесть — структурная основа.
Принципиальная особенность модели — обработка входящего сообщения раздроблена на два независимых процесса: быстрый приём с сохранением в локальный пул и подтверждением шине, плюс отдельный отложенный процесс прикладной обработки из пула. Это даёт ссылочную целостность при разрозненном порядке прихода связанных сообщений и не блокирует шину на время прикладной логики. Концептуальные основания — в Концепции / Жизненный цикл сообщения и Концепции / Параллелизм.
Архитектурная схема
flowchart TD
subgraph sys["Учётная система (1С / ERP / …)"]
subgraph adapter["Модуль интеграции (адаптер)"]
Events["Обработчики событий учётной системы"]
OutH["Исходящие обработчики"]
OutQ["Локальная очередь исходящих"]
Tr["Транспорт · REST-клиент"]
InP["Локальный пул входящих · приём + ACK"]
InH["Входящие обработчики"]
DB["Применение в БД учётной системы"]
Events -->|событие| OutH
OutH --> OutQ
OutQ -->|регламент: отправка| Tr
Tr -->|регламент: приём| InP
InP -->|регламент: обработка| InH
InH --> DB
end
end
Tr -->|"HTTPS · отправка и получение"| DH["DataHUB · backend"]
Ключевая структурная деталь — локальный пул входящих как буфер между транспортом и обработчиками. Транспорт пишет в пул и сразу подтверждает шине; обработчики читают из пула по своему расписанию. Шина в обработку не вмешивается.
Локальная очередь исходящих
Назначение. Не пытаться отправлять сообщение «прямо сейчас, синхронно» в момент его формирования, а откладывать в собственное персистентное хранилище. Это позволяет:
- Не зависеть от состояния шины при выполнении пользовательских операций (создание документа не должно валиться, потому что DataHUB недоступен).
- Накапливать сообщения в офлайн-режиме и отправлять их при восстановлении связи.
- Управлять порядком отправки и приоритетами на стороне клиента.
Реализация. Зависит от платформы:
- В 1С — регистр сведений «Очередь исходящих сообщений» (или аналогичный).
- В Java/.NET — таблица в БД приложения или встроенный брокер.
- В Python — таблица в БД или файловый каталог.
Свойства, которые должна обеспечить очередь:
- Персистентность (переживает рестарт приложения).
- Идентификатор сообщения, стабильный между попытками отправки.
- Признак статуса (в очереди / отправлено / ошибка / подтверждено шиной).
- Метаданные для повтора (количество попыток, время последней).
Локальный пул входящих
Назначение. Принять сообщение из шины и быстро подтвердить (ACK), чтобы шина перестала за него отвечать. Реальное применение сообщения к бизнес-данным произойдёт отдельно — из этого же пула, отложенно, по расписанию или по событию.
Без пула обработка входящих неминуемо ломается на ссылочной связности: накладная пришла раньше контрагента → её нельзя применить → нужно либо синхронно ждать связанную сущность, либо отказывать шине в ACK и зацикливать ретраи через её очередь. Локальный пул разрывает этот узел: ACK отдаётся как только запись попала в пул, а отложенный обработчик может ретраить применение сколько угодно раз и через любые интервалы.
Реализация. Зависит от платформы:
- В 1С — регистр сведений «Входящие сообщения» или одноимённый справочник со статусной обработкой.
- В Java/.NET — таблица в БД приложения.
- В Python — таблица в БД или отдельная служебная коллекция.
Свойства, которые должен обеспечить пул:
- Персистентность.
- Уникальный индекс по
idсообщения — для идемпотентного приёма (повторная вставка того жеidраспознаётся и игнорируется). - Статус записи:
новое→обрабатывается→обработано/ошибка обработки/отложено. - Метаданные для отложенной обработки: количество попыток, время следующей попытки, причина последней ошибки.
- Сохранение payload в исходном виде — для возможности повторной обработки и аудита.
Транспорт
Клиент REST API DataHUB. Обязанности:
- Управление авторизацией: получение access-токена через service token, обновление по refresh при истечении.
- Сериализация исходящих сообщений в формат API.
- Отправка через HTTPS, обработка кодов ответа.
- Получение входящих (poll или long-poll).
- Отправка подтверждений (ACK).
- Отправка отказов (NACK) при бизнес-ошибках.
В большинстве платформ это слой из ~5–10 функций, инкапсулирующий все HTTP-вызовы. Детальный API — Транспортный API. Авторизация — Безопасность.
Обработчики исходящих
Превращают события учётной системы в сообщения. Типовая структура:
Событие в учётной системе (Подписка / Триггер / Хук)
│
▼
Обработчик исходящих:
- определить тип события (создание/изменение/удаление)
- извлечь данные документа
- сформировать payload по контракту пакета обмена
- сгенерировать стабильный id сообщения
- положить в локальную очередь исходящих
Ключевые требования:
- Запись в очередь — в той же транзакции, что и изменение в БД учётной системы. Иначе возможны рассогласования: документ создан, а сообщение об этом не сформировано (или наоборот).
- Стабильный идентификатор сообщения. Если по тому же документу позднее формируется новое сообщение (например, при изменении) — это новое сообщение с новым
id, а не та же запись. - Никакой бизнес-логики. Обработчик только перекладывает; вся логика — в самой учётной системе.
Обработчики входящих
Применяют принятые сообщения к бизнес-данным учётной системы. Не работают напрямую с транспортом — берут сообщения уже из локального пула. Это вторая фаза двухфазной модели обработки.
Структура:
Регламент отложенной обработки (по расписанию или по событию)
│
▼
Обработчик входящих:
- выбрать из пула запись со статусом «новое» или «отложено»
- пометить «обрабатывается»
- преобразовать payload в типовые значения
- разрешить ссылки на другие сущности
- применить бизнес-логику (создать/обновить документ, справочник, …)
- закоммитить транзакцию учётной системы
- перевести запись в пуле в статус «обработано»
при ошибке отсутствия ссылки:
- откатить
- перевести запись в статус «отложено»
- задать время следующей попытки и увеличить счётчик
при критической ошибке (битый payload, неустранимое противоречие):
- откатить
- перевести запись в статус «ошибка обработки»
- оставить для разбора администратором
Ключевые требования:
- Идемпотентность — обязательна на обеих фазах: фаза приёма должна корректно отрабатывать повторную доставку шиной (защита через уникальный индекс пула), фаза обработки — повторные попытки из пула (защита через проверку «не превратилась ли уже эта запись в документ»).
- ACK шине — на фазе приёма, не на фазе обработки. После записи в пул и коммита транзакции пула транспорт сразу же отправляет ACK. Применение к бизнес-данным происходит позже, в отдельной транзакции, к которой шина уже не имеет отношения.
- Никакой бизнес-логики «снаружи» от документа. Сообщение создаёт или изменяет одну сущность; всё, что должно произойти дальше (пересчёт остатков, движения регистров, расчёт цен), — это логика учётной системы, которая срабатывает по созданию или изменению этого документа.
- Параметры отложенной обработки настраиваются администратором модуля. Интервал отсрочки при ошибке ссылки и максимальное число попыток подбираются под производительность сервера и характер входящих данных. Жёстких значений «из коробки» нет.
Регламентные задания
Фоновая работа, без которой адаптер не сможет автоматически синхронизироваться:
| Задание | Что делает | Типичная периодичность |
|---|---|---|
| Отправка исходящих | Берёт из локальной очереди сообщения «в очереди», отправляет через транспорт. При успехе — переводит в «отправлено». При ошибке — увеличивает счётчик попыток | Каждые 1–5 минут |
| Приём входящих | Опрашивает шину за новыми сообщениями. Получённые — кладёт в локальный пул входящих со статусом «новое» и сразу отправляет ACK шине | Каждые 1–5 минут (для poll) или непрерывно (для long-poll) |
| Отложенная обработка входящих | Берёт из пула входящих записи со статусом «новое» или «отложено» (по которым подошло время следующей попытки), запускает обработчики, переводит в «обработано» / «отложено» / «ошибка обработки» | Каждые 1–5 минут, может выполняться параллельно в несколько потоков |
| Повтор отправки | Берёт из очереди сообщения с ошибкой отправки, давностью больше N, повторяет | Каждые 10–60 минут |
| Очистка истории | Удаляет старые «обработанные» записи из пулов (за регламентный срок). Записи в статусе «ошибка обработки» не удаляются автоматически — только после ручного разбора | Раз в сутки |
Конкретные интервалы — параметры конфигурации модуля, не платформы.
Граница ответственности
Очень важная архитектурная граница: модуль интеграции не занимается бизнес-логикой.
- Сформировать сообщение для отправки — модуль (но что отправлять и когда — учётная система).
- Применить пришедшее сообщение в БД — модуль (но реакция на это применение — учётная система).
- Защита от дубликатов — модуль (потому что это техническая задача).
- Валидация бизнес-правил — учётная система (модуль их не знает и не должен знать).
- Расчёт цен, пересчёт остатков, проводки — учётная система.
Эта граница позволяет модулю интеграции жить относительно стабильно, пока бизнес-логика учётной системы эволюционирует, и наоборот.
Что вне ответственности модуля
- Хранение бизнес-данных. Сообщения проходят через модуль, но после подтверждения удаляются из локальной очереди; постоянное хранение — в учётной системе.
- Маршрутизация. Куда уйдёт сообщение, решает шина по своим правилам — модуль только указывает тип и (опционально) адресата.
- Обеспечение порядка обработки между разными очередями. Если бизнес-логике нужен строгий порядок между несколькими сообщениями — это её задача, не модуля.
Что дальше
- Модули интеграции / 1С — реализация описанной модели для платформы 1С.
- Транспортный API — детальная спецификация REST-вызовов.
- Концепции / Идемпотентность — почему обработчики обязаны быть идемпотентны.
- Концепции / Параллелизм — почему отложенная обработка нужна и почему нельзя «всё в один поток».