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

Жизненный цикл сообщения

Сообщение в DataHUB живёт от события в системе-источнике, по которому оно должно быть сформировано, до фиксации результата в системе-приёмнике. Этот путь раскладывается на три части, выполняемые независимыми процессами в разных слоях.

Описание ниже — концептуальное; конкретные имена регистров, процедур и других технических артефактов в типовом 1С-модуле — в Модулях интеграции / 1С / Алгоритмы обмена.

Часть 1 — Формирование исходящего на стороне источника

Шаг 1. Регистрация объекта. В учётной системе происходит событие, по которому должно быть сформировано сообщение обмена (запись документа, изменение справочника). Срабатывает подписка на это событие. Выполняется простой код без блокировок, не влияющий на интерактивную работу пользователя: в локальную очередь регистрации записывается ссылка на изменённый объект или его сериализованное представление.

Принцип «без блокировок» — критический: пользователь должен иметь возможность сохранить документ и продолжить работу, не дожидаясь подключения к шине и формирования сообщения.

Шаг 2. Формирование сообщения. Сразу после регистрации (не по расписанию, а по событию) запускается отдельный процесс формирования. Если зарегистрировано несколько объектов, запускается несколько потоков.

Для каждого объекта:

  • Берётся соответствующий исходящий обработчик (по типу объекта).
  • Обработчик формирует структуру для выгрузки.
  • Структура сериализуется в сообщение обмена.
  • Сообщению присваивается уникальный идентификатор для сквозной трассировки.
  • Сообщение помещается в локальную очередь отправки модуля.

Шаг 3. Отправка в шину. Из очереди отправки потоки отправки берут сообщения и публикуют через API шины. Шина возвращает подтверждение приёма — сообщение переводится в статус «отправлено» в очереди модуля.

Часть 2 — Передача через шину

Принятое шиной сообщение попадает в точку обмена и из неё распределяется по очередям систем-приёмников в соответствии с настроенными маршрутами для класса сообщения.

Приёмник, подключённый к шине, получает сообщения из своей очереди — обычно по подписке, без опроса: как только сообщение появилось, шина его выдаёт.

Шина в этой части — пассивный транспорт: она не вмешивается в содержимое, не валидирует, не пересобирает.

Часть 3 — Приём и обработка на стороне приёмника

Шаг 4. Приём в локальный пул. Полученное из шины сообщение записывается в локальный пул входящих модуля приёмника — операция короткая, на ней подтверждается приём шине. Сразу после успешного коммита записи в пул отправляется ACK шине; сообщение из очереди шины удаляется, она больше за него не отвечает.

Шаг 5. Прикладная обработка. Как только в пуле появляются необработанные сообщения, запускаются потоки обработки. Для каждого сообщения:

  • Берётся соответствующий входящий обработчик (по классу сообщения).
  • Запускается процедура обработки.
  • Формируются внутренние ссылки (поиск объектов по их внешним идентификаторам — см. Идентификация объектов между системами).
  • Проводится проверка заполнения и бизнес-валидация.
  • При успехе — записывается бизнес-объект в БД учётной системы.
  • Сообщение переводится в статус «обработано».

Зачем шаги 4 и 5 разделены

Принципиально важная деталь: ACK шине отдаётся в шаге 4, до прикладной обработки в шаге 5. Этому есть три причины.

Ссылочная целостность. Сообщение-документ может прийти раньше сообщения-справочника, на который оно ссылается. Если обрабатывать на лету в момент приёма, такая ситуация валит обработку, и сообщение нужно ретраить. Ретрай через возврат в очередь шины раздувает её и не гарантирует, что нужное справочное сообщение придёт между попытками. Локальный пул + отложенная обработка позволяют ретраить применение сколько угодно раз и через любые интервалы внутри модуля.

Приоритезация. Из локального пула можно разбирать сообщения с приоритетом по типу — сначала оперативные документы (заказы, накладные, оплаты), потом справочники и прочие статичные сущности. Через очереди шины приоритезация по бизнес-типу внутри одного получателя нереализуема.

Быстрое освобождение шины. Шина освобождается от сообщения, как только оно записано в локальный пул, не блокируется на время прикладной обработки, которая может занять секунды или минуты.

Статусы

Каждое сообщение в локальном пуле модуля имеет статус, отражающий его текущее положение в жизненном цикле. Концептуально статусы делятся на промежуточные (сообщение движется) и терминальные (движение завершено).

Для исходящего потока:

Статус Когда возникает
Новое Сообщение сформировано обработчиком, ещё не в очереди отправки
Ожидание отправки В очереди отправки, ждёт потока отправки
Отправлено Шина подтвердила приём — терминальный успех
Отправка отменена Администратор/процесс отменил отправку — терминальный

Для входящего потока:

Статус Когда возникает
Новое Принято из шины, записано в локальный пул
Ожидание обработки В пуле, ждёт потока обработки
В обработке Обработчик сейчас выполняется
Обработано Успешно применено к БД — терминальный успех
Ошибка обработки Сбой в обработчике — терминальный, требует разбора
Отсутствует обработчик Для класса сообщения нет включённого обработчика — терминальный, см. Обработчики интеграции
Обработка отменена Администратор отменил — терминальный

Терминальные статусы успеха — нормальное завершение. Терминальные статусы ошибок и отмен — материал для разбора администратором; пока разбор не сделан, сообщения остаются в пуле модуля.

Сквозной идентификатор

На всём пути от шага 2 до шага 5 у сообщения сохраняется один и тот же идентификатор. По нему сообщение можно отследить от формирования на источнике через шину до применения на приёмнике, в том числе через статусы на каждом конце.

Если шина по какой-то причине доставит то же сообщение второй раз (типичный сценарий — сетевой сбой между «записали в пул» и «отдали ACK»), у приёмника окажется два появления сообщения с одним и тем же идентификатором. Это распознаётся как дубликат — см. Идемпотентность.

Что дальше