Прежде всего нужно разобраться, что такое «брокер сообщений». Википедия говорит:
Брокер сообщений — архитектурный паттерн в распределённых системах. Приложение, которое преобразует сообщение по одному протоколу от приложения-источника в сообщение протокола приложения-приёмника, тем самым выступая между ними посредником.
Но если сказать простыми словами, брокер сообщения это сервис, который умеет принимать сообщения от клиента, хранить их и передавать их другому клиенту.
По сути, почтовый сервер также можно назвать брокером сообщений, и FTP сервер, и даже расшаренная папка на сервере может выступать посредником передачи сообщений.
Только когда в качестве брокера будет выступать такой примитивный сервис, как почтовый или FTP, то ряд вспомогательных функций — удаление сообщений после прочтения, определение очерёдности чтения, подтверждение получения сообщения и другие — будут ложиться на клиента. А полноценный брокер сообщений, например, Rabbit MQ все это берет на себя и предлагает ряд других возможностей, например, очередь и маршрутизацию.
Почему брокеры сообщений получили такое сильное распространение
На рынке есть много разных платформ, разработанных на разных языках программирования, и задача реализации обмена между разными системами достаточно сложная и затратная. По этой причине спрос создал потребность в сторонних сервисах, которые бы выступали посредниками и имели хорошо документированное API для реализации отправки и чтения сообщений. Я думаю, для всех более-менее известных языков программирования и фреймворков существуют готовые библиотеки для взаимодействия с Rabbit MQ. Разработчики по умолчанию выбирают этого брокера сообщений в своих проектах.
Как обстоит дело с Rabbit MQ в 1С
Есть 2 варианта:
- Использовать внешнюю Native API компоненту.
- Использовать HTTP API.
Особенности работы через HTTP API
Rabbit MQ хоть и имеет HTTP API, оно больше предназначено для администрирования сервиса, чем для обмена, имеет ряд ограничений (например, не поддерживает подтверждение принятия каждого сообщения ack) и работает достаточно медленно. В отзывах пишут, что бывают потери сообщений. Используют это решение мало, но есть примеры успешной реализации, например описанные здесь //infostart.ru/1c/tools/1731834/.
Из плюсов — простота реализации и отсутствие внешних компонент.
Для более продвинутого варианта остаётся только использовать внешние библиотеки. На данный момент мне известно 2 основных решения:
- PinkRabbitMQ от BIT:ERP, бесплатно доступна на GITHUB https://github.com/BITERP/PinkRabbitMQ
- Интеграция от Серебряной пули (платная) https://silverbulleters.org/rabbitmq
- Есть также разные решения, размещенные на Infostart, например, описанные в статье //infostart.ru/1c/tools/845345/.
Установка Rabbit MQ для тестирования обмена
Наверное, установка такой системы, как Rabbit MQ, могла быть нетривиальной задачей. Хотя, надо сказать, документация на сайте очень хорошая, хоть и англоязычная: https://www.rabbitmq.com/download.html
Но есть вариант гораздо проще и быстрее — развернуть готовый docker контейнер. Так и поступим. Изначально должен быть установлен сам Docker. Это тоже не проблема, есть клиент под Windows с интуитивно понятным интерфейсом: https://www.docker.com/products/docker-desktop/
После установки Docker, перезагрузки и возможно обновления подсистемы WSL (все инструкции даст сам Docker) достаточно открыть терминал и выполнить команду:
docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 -e RABBITMQ_DEFAULT_USER=rabbit -e RABBITMQ_DEFAULT_PASS=rabbit rabbitmq:3.12-management
Обратите внимание, здесь есть небольшая модификация, я задал пользователя и пароль для сервиса. Так удобнее работать. Пароль по умолчанию был guest.
Сразу оставлю небольшую справку, по работе с контейнером:
1. Чтобы остановить контейнер, необходимо выполнить:
docker stop rabbitmq
2. Чтобы запустить:
docker start rabbitmq
3. Чтобы удалить:
docker rm rabbitmq
Можно управлять контейнером и через интерфейс программы Docker-desktop.
После установки можно сразу открыть страницу управления Rabbit MQ по адресу http://localhost:15672
А после логина мы попадаем в основное окно Rabbit MQ
Никаких настроек пока делать не будем и перейдём к реализации обмена в 1С. В процессе станет понятно, какие настройки понадобятся.
Отправка сообщений в Rabbit MQ из 1С
Я буду использовать решение PinkRabbitMQ от BIT:ERP. Первое, нам потребуется библиотека, которую можно скачать с GITHUB https://github.com/BITERP/PinkRabbitMQ/releases/tag/addins_PinkRabbitMQ_149.
В релизах есть несколько версий, чтобы в одной базе можно было подключить несколько экземпляров одной библиотеки для разных обменов.
Скачанный архив я поместил в общий макет. Подключить компоненту можно командой
Подключено = Ждать ПодключитьВнешнююКомпонентуАсинх("ОбщийМакет.PinkRabbitMQ", "BITERP", ТипВнешнейКомпоненты.Native);
Не буду заострять внимание на подключении, пример можно посмотреть в синтакс-помощнике 1С.
Более интересен процесс отправки и получения сообщений. Отправка сообщений осуществляется методом BasicPublish. Но перед этим следует установить соединение с сервисом Rabbit MQ методом Connect.
ИмяТочкиОбмена = "data";
ИмяОчереди = "project";
ОтправляемоеСообщение = "Test";
Компонента = Ждать RebbitMQКлиент.ПолучитьКомпоненту();
Компонента.Connect("localhost", 5672, "rabbit", "rabbit", "/");
Компонента.BasicPublish("", ИмяОчереди, ОтправляемоеСообщение, 0, Ложь);
Для подключения нам необходимо знать адрес сервиса, порт, пользователя и пароль. Все это было задано в момент установки Rabbit MQ. Для того чтобы отправить или получить сообщения, нужно знать Exchanges (имя точки обмена) и Queues (имя очереди), их мы и передаём в методе BasicPublish. Настроить их проще всего через интерфейс сервиса, но, если требуется, библиотека позволяет создать их программно.
На странице Exchanges добавим точку обмена.
А на странице Queues and Streams добавим очередь.
Ещё есть параметр Virtual host (виртуальный хост), по умолчанию он равен «/» и, как правило, не меняется.
После этих настроек можно выполнить код, описанный выше.
Получение сообщений
Получение сообщений происходит методом BasicConsumeMessage. Но перед его вызовом ещё требуется использовать метод BasicConsume, который начинает чтение и регистрирует потребителя сообщений для очереди. Для чтения достаточно знать только имя очереди.
ИмяОчереди = "project";
ОтправляемоеСообщение = "";
НеЖдать = Ложь; //noConfirm
ТегСообщения = 1;
ОтветноеСообщение = "";
Компонента = Ждать RebbitMQКлиент.ПолучитьКомпоненту();
Компонента.Connect("localhost", 5672, "rabbit", "rabbit", "/");
Потребитель = Компонента.BasicConsume(ИмяОчереди, "", НеЖдать, Ложь, 0);
Если Компонента.BasicConsumeMessage("", ОтветноеСообщение, ТегСообщения, 100) Тогда
Компонента.BasicAck(ТегСообщения);
Сообщить("Успешно! Из очереди прочитано сообщение " + ОтветноеСообщение);
КонецЕсли;
Компонента.BasicCancel("");
Обратите внимание ещё на один метод BasicAck. Он отсылает серверу подтверждение (ack), что сообщение обработано и его можно удалить.
Это метод работает вместе с параметром noConfirm, который указывает сервису очищать очередь после прочтения любого сообщения или ждать ответ методом BasicAck.
Т.е. если noConfirm установить в значение Истина, очередь будет автоматически очищаться. В таком случае нам нужно сразу читать все сообщения.
Если мы отказываемся от автоматической очистки очереди, то с помощью метода BasicAck мы можем подтвердить прочтение сообщения и только после этого оно будет удалено. Переменная ТегСообщения, которая устанавливается в методе BasicConsumeMessage, содержит номер прочитанного сообщения. Он передаётся в метод BasicAck.
Здесь я описал минимум, который достаточен, чтобы организовать обмен с брокером сообщений Rabbit MQ.
Пример реализации обмена выложен на GitHUB. Можно клонировать проект по адресу git@github.com:free-archer/RabbitMQ_Simle.git и развернуть в EDT, а можно просто скачать выгрузку конфигурации и базы https://github.com/free-archer/RabbitMQ_Simle/releases/tag/v1.0.
В конфигурации реализован пример работы с Rabbit MQ на клиенте и на сервере. Настройки подключения хранятся в регистре. Это позволяет легко настроить подключения и проверить работоспособность сервиса.
Заключение
Хочется вернуться к вопросу, который я обозначил вначале, и понять, какую нишу брокеры сообщений занимают в инфраструктуре 1С.
Если 1С обменивается со сторонними системами, разработанными не на платформе 1С, выбор брокера сообщений, скорее всего, будет продиктован разработчиками этой системы. И Rabbit MQ может быть выбран как самый популярный и проверенный временем брокер.
Но нужен ли брокер, если обмен строится между системами, разработанными на платформе 1С? Вопрос не простой. По моему мнению, с обменом большими порциями данных лучше справится типовой обмен БСП по технологии КД2 или КД3. И применение брокера сообщений не даст особых преимуществ, а только усложнит систему