Классические механизмы интеграции в экосистеме 1С:Предприятие традиционно базируются на планах обмена (компонентах БСП) и периодической пакетной выгрузке данных в формате XML. На малых базах эта схема работает отлично, но при росте нагрузки, увеличении количества связанных информационных систем и повышении требований к актуальности данных классический обмен начинает давать сбои. Огромные XML-пакеты нагружают оперативную память, транзакции блокируют таблицы СУБД, а разбор ошибок превращается в детективное расследование, когда из-за одного некорректного документа "откатывается" весь многомегабайтный пакет.
Альтернативой является переход к событийной архитектуре (Event-Driven Architecture, или EDA) с использованием внешних брокеров сообщений (RabbitMQ, Apache Kafka, NATS). В этой статье мы подробно разберем, как устроен гарантированный обмен сообщениями между 1С и внешними брокерами, проанализируем статус технологии NATS Streaming и рассмотрим новые архитектурные решения от самой фирмы 1С.
В исходном обсуждении автор интересуется возможностью использования NATS Streaming в режиме гарантированной доставки (Durable). Разберем этот вопрос с технической точки зрения.
Прежде всего, важно знать, что проект NATS Streaming (также известный как STAN) официально признан устаревшим (deprecated). Разработчики прекратили его активную поддержку и выпуск новых функций. Использовать его в новых проектах в промышленной эксплуатации крайне не рекомендуется по следующим причинам:
Ему на смену пришла современная технология — NATS JetStream, которая теперь встроена непосредственно в ядро NATS Server (начиная с версии 2.2). JetStream полностью решает проблемы старого STAN:
Таким образом, если вы рассматриваете стек NATS для интеграции с 1С, ваш выбор — исключительно NATS JetStream.
Основной страх разработчиков при отказе от классических планов обмена 1С — это потеря контроля над доставкой. В планах обмена источник хранит регистрацию изменений до тех пор, пока получатель не пришлет подтверждение (квитанцию). Как реализовать аналогичную надежность с брокером сообщений?
Для этого применяется классический архитектурный паттерн — Transactional Outbox (Локальная таблица исходящих) на стороне отправителя и Idempotent Consumer (Идемпотентный получатель / Локальная таблица входящих) на стороне получателя. Разберем эту схему по шагам:
ЛокальнаяОчередьИсходящих) внутри той же транзакции, в которой записывается сам документ.ЛокальнаяОчередьИсходящих и пытается отправить их в брокер сообщений.ЛокальнаяОчередьИсходящих. Если брокер недоступен или произошел сбой сети, транзакция отправки не завершается, данные остаются в 1С и попытка повторится через интервал времени.ЛокальнаяОчередьВходящих, подтверждая брокеру прием. С этого момента брокер считает сообщение доставленным.ЛокальнаяОчередьВходящих, создавая или обновляя соответствующие объекты 1С. После успешной записи объекта сообщение удаляется из входящей очереди.Рассмотрим пример реализации записи в локальную исходящую очередь на встроенном языке 1С внутри транзакции проведения документа:
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
// Выполняем стандартные действия по проведению документа
// ...
// Начинаем подготовку сообщения для брокера
ДанныеДокумента = Новый Структура;
ДанныеДокумента.Вставить("Идентификатор", Строка(Ссылка.УникальныйИдентификатор()));
ДанныеДокумента.Вставить("Номер", ЭтотОбъект.Номер);
ДанныеДокумента.Вставить("Дата", Формат(ЭтотОбъект.Дата, "ДФ=yyyy-MM-ddTHH:mm:ss"));
ДанныеДокумента.Вставить("ОрганизацияИНН", ЭтотОбъект.Организация.ИНН);
ДанныеДокумента.Вставить("КонтрагентИНН", ЭтотОбъект.Контрагент.ИНН);
ДанныеДокумента.Вставить("Сумма", ЭтотОбъект.СуммаДокумента);
// Сериализуем данные в формат JSON
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, ДанныеДокумента);
ТелоJSON = ЗаписьJSON.Закрыть();
// Записываем сообщение в транзакции в таблицу Outbox (регистр сведений)
МенеджерЗаписи = РегистрыСведений.ЛокальнаяОчередьИсходящих.СоздатьМенеджерЗаписи();
МенеджерЗаписи.ИдентификаторСообщения = Строка(Новый УникальныйИдентификатор());
МенеджерЗаписи.ТипСобытия = "Документ_РеализацияТоваровУслуг";
МенеджерЗаписи.ТелоСообщения = ТелоJSON;
МенеджерЗаписи.ДатаРегистрации = ТекущаяДатаСеанса();
// Метод Записать() выполнится в рамках общей транзакции проведения.
// Если проведение откатится, сообщение не попадет в таблицу отправки.
МенеджерЗаписи.Записать(Истина);
КонецПроцедуры
Переход на точечную отправку JSON-сообщений дает колоссальные преимущества для крупных корпоративных систем:
В конце обсуждения участники форума упоминают "мотоцикл от вендора", который должен решить проблему написания собственных велосипедов для работы с очередями. Речь идет о продукте "1С:Шина" (1C:Enterprise Service Bus), который фирма 1С выпустила как раз для решения задач асинхронной интеграции.
"1С:Шина" представляет собой отдельное серверное ПО, построенное на новой технологии "1С:Предприятие 8" (на базе среды разработки "1С:Элемент"). Она решает следующие задачи:
Кроме того, начиная с версии платформы 1С:Предприятие 8.3.16, разработчикам доступен встроенный механизм — Сервисы интеграции. Этот объект метаданных позволяет автоматизировать отправку сообщений во внешние системы напрямую из кода 1С:
Проанализировав развитие технологий интеграции в 1С, мы можем сформулировать следующие рекомендации:
СервисыИнтеграции платформы.