Структура сообщения обмена
Сообщение обмена — атомарная единица передачи через DataHUB. У него два уровня: служебный блок (envelope) — нужен шине и общему процессу обмена — и содержимое (body) — данные передаваемой бизнес-сущности.
В обиходе сообщение обмена иногда называют «пакетом обмена» (по аналогии с сетевыми пакетами) — это синонимы.
Служебный блок
Шина видит и использует только служебный блок — для приёма, маршрутизации, трассировки. Бизнес-смысл содержимого она не интерпретирует. В служебный блок входят:
- Идентификатор сообщения — уникальный код самого сообщения в шине. Стабилен на всём пути «отправка → доставка → подтверждение → возможный ретрай». По нему сообщение отличается от других, в том числе при повторных доставках того же сообщения.
- Тип сообщения — служебный признак, обычно
DATAдля прикладных данных. - Класс сообщения — класс, к которому относится сообщение. По нему шина выбирает маршруты, а приёмник — обработчик.
- Время создания — момент формирования сообщения отправителем, в каноническом виде.
- Идентификатор системы-источника — ссылка на запись об отправителе в компании.
Эти поля присутствуют во всех сообщениях независимо от класса. Они — общий контракт между шиной и любым клиентским модулем.
Содержимое
Внутри сообщения помимо служебного блока есть собственно payload — данные бизнес-сущности. Структура payload полностью определяется классом сообщения и его контрактом, согласованным между участниками обмена.
Содержимое делится на две функционально различные части:
Идентификаторы передаваемой сущности — блок, по которому приёмник распознаёт, какому объекту в его БД это сообщение соответствует. Поскольку у одной бизнес-сущности в разных системах разные внутренние идентификаторы, передаётся массив известных идентификаторов — каждый указывает на одну из систем-участников и идентификатор сущности внутри неё. Подробно — в Идентификации объектов между системами.
Бизнес-атрибуты — собственно данные документа, справочника или события: реквизиты, табличные части, метки времени и прочее. Если атрибут ссылается на другую бизнес-сущность, эта ссылка тоже передаётся как массив известных идентификаторов — по той же схеме, что и основная сущность. Состав атрибутов — задача контракта класса, не шины.
Атомарность сообщения
Каждое сообщение передаёт ровно одну бизнес-сущность. Если нужно передать две связанные, но независимые сущности — создаются два класса сообщений и каждая сущность передаётся отдельным сообщением.
Объединить несколько сущностей в один класс допустимо, если:
- они неразделимы по смыслу в учётной системе,
- одна не может существовать без другой,
- у них циклические ссылки друг на друга.
Перечислимые типы — фиксированные наборы значений с конечным числом элементов — допускается включать в состав класса, не создавая для них отдельного класса сообщений.
Что вне сообщения
Несколько вещей сознательно вынесены за пределы сообщения и живут отдельно:
Маршруты доставки. Куда сообщение пойдёт, решает шина по маршрутам. Отправитель не указывает список получателей в сообщении — только класс и (опционально) явного адресата.
Бинарные файлы. Они передаются по ссылке, а не внутри payload — см. Обмен файлами. В payload остаётся URL, размер, имя, контрольная сумма; сам файл — в выделенном хранилище.
История доставки. Шина не хранит сообщения после их подтверждения получателем — после ACK сообщение удаляется из её очереди. Видимость прохождения сохраняется на стороне клиентского модуля (в типовом 1С-модуле — отдельная страница со статусами исходящих и входящих).
Размер
Шина рассчитана на короткие структурированные сообщения — единицы и десятки килобайт payload. Это сознательное ограничение:
- Большие сообщения тормозят остальные: пока обработчик читает мегабайтный JSON, остальные сообщения в очереди ждут.
- Большие сообщения хуже переживают сетевые сбои — больше шанс таймаута, выше стоимость ретрая.
- Большие сообщения дублируются на каждого получателя при веерной рассылке.
Если в обмене нужно передать большой объём данных — это файл, и он должен идти как файл по ссылке (см. Обмен файлами), а не как раздутый payload.
Что дальше
- Типы данных — какие типы значений допустимы внутри payload.
- Классы сообщений — что определяет конкретный состав полей.
- Идентификация объектов между системами — как устроен блок идентификаторов внутри content.
- Обмен файлами — почему файлы — отдельная история.
- Архитектура / Структура пакетов — конкретный wire-формат для разработчика.