Перейти к содержанию

Архитектура модулей интеграции

Платформа DataHUB сама по себе не делает обмен — она предоставляет API, к которому подключаются клиентские системы. На стороне каждой клиентской системы должен быть свой модуль интеграции (адаптер): код, который умеет формировать сообщения в формате шины, отправлять их через REST API, забирать входящие, обрабатывать их и подтверждать.

Готовые модули интеграции описаны в разделе Модули интеграции. Эта статья описывает общую модель клиентского модуля, по которой проектируется любой адаптер, независимо от языка и платформы.

Что делает модуль интеграции

Любой модуль интеграции, чтобы корректно работать с шиной, должен реализовать шесть обязательных блоков функциональности:

  1. Локальная очередь исходящих сообщений — буфер, в который кладутся сообщения, ожидающие отправки.
  2. Локальный пул входящих сообщений — таблица в БД получателя, куда складываются принятые сообщения до момента прикладной обработки.
  3. Транспорт — клиент REST API DataHUB: авторизация, отправка, получение, подтверждение.
  4. Обработчики исходящих — код, который превращает события учётной системы (создан документ, изменён справочник) в сообщения.
  5. Обработчики входящих — код, который применяет сообщения из локального пула к бизнес-данным учётной системы.
  6. Регламентные задания — фоновая работа: отправка накопленного, приём новых, отложенная обработка, переотправка не подтверждённых.

Этот набор — необходимый и почти достаточный. Дополнительные элементы (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 минут
Очистка истории Удаляет старые «обработанные» записи из пулов (за регламентный срок). Записи в статусе «ошибка обработки» не удаляются автоматически — только после ручного разбора Раз в сутки

Конкретные интервалы — параметры конфигурации модуля, не платформы.

Граница ответственности

Очень важная архитектурная граница: модуль интеграции не занимается бизнес-логикой.

  • Сформировать сообщение для отправки — модуль (но что отправлять и когда — учётная система).
  • Применить пришедшее сообщение в БД — модуль (но реакция на это применение — учётная система).
  • Защита от дубликатов — модуль (потому что это техническая задача).
  • Валидация бизнес-правил — учётная система (модуль их не знает и не должен знать).
  • Расчёт цен, пересчёт остатков, проводки — учётная система.

Эта граница позволяет модулю интеграции жить относительно стабильно, пока бизнес-логика учётной системы эволюционирует, и наоборот.

Что вне ответственности модуля

  • Хранение бизнес-данных. Сообщения проходят через модуль, но после подтверждения удаляются из локальной очереди; постоянное хранение — в учётной системе.
  • Маршрутизация. Куда уйдёт сообщение, решает шина по своим правилам — модуль только указывает тип и (опционально) адресата.
  • Обеспечение порядка обработки между разными очередями. Если бизнес-логике нужен строгий порядок между несколькими сообщениями — это её задача, не модуля.

Что дальше