RabbitMQ + 1С. Быстрый старт

Обмен - Обмен с другими системами

62
Внешняя компонента для отправки сообщения из 1С в кролика. Сервис прослушивания и перенаправления сообщений из кролика в http или web-сервис.

Здравствуйте.

Описанные ниже мысленные изыскания были навеяны статями сильвер булетов и прочих товарищей по использованию очередей на основе RabbitMQ. Описывать, что, как и зачем использовать этот брокер мессенджер не вижу смысла - в предыдущих статьях все хорошо описано. Здесь я опишу сугубо практику применения.

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

Основной обмен происходил файлами через файлопомойку без какого-либо оповещения об обработке входящих данных и т.п. Зачастую получалась ситуация, что данные отправлены, что-то пошло не так, данные не получены системой получателем, но система отправитель об этом ни сном ни духом. В результате получаем бесконечный поток писем в поддержку "Где наши платежи/заказы/etc?! В рознице деньги оприходовали/заказ провели,, а на сайт они не попали" и т.п. На диагностику проблемы уходило безумное количество времени, потому что, чтобы понять причину сотрудник поддержки:

  1. Смотрел лог отправки в системе отправителе.
  2. Проверял, что файла нет в папке получателе. (данные не стоят в очереди)
  3. Проверял, что файл есть в архивной папке системы получателя (данные получены и обработаны)
  4. Проверял данные самого файла.
  5. Проверял логику формирования данных.

И это на каждое письмо. Теперь:

  1. Открывает лог отправки данных в системе отправителе и смотрит в нем все статусы пакета данных (дата отправки, дата получения, ссылка на текст отправленных данных).
  2. Проверяет логику формирования данных.

В итоге получаем значительную экономию времени. Думаю, у каждого таких примеров наберется немало.

Итак, выбор пал на RabbitMQ (далее, Кролик). К сожалению, я не обнаружил сразу описания HTTP интерфейса Кролика, а на глаза попала библиотека для C# на самом сайте Кролика. Было решено в исследовательских целях написать COM-компоненту на коленке и небольшой сервис (службу) для обслуживания входящих сообщений и направлений их к адресату.

Компоненту можно регистрировать, как 32, так и 64 битную, зависит от того, какой версией регасма будете регистрировать. В итоге для работы сервера с ней нет необходимости оборачивать ее в COM+. Регистрация компоненты проходит regasm'ом, а не regsvr32:

64 бита:

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regasm /codebase <Путь к файлу компоненты>

32 бита:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\regasm /codebase <Путь к файлу компоненты>

Не знаю, обязателен ли ключ /codebase, но я регистрировал с ним. Версию .NET фреймворка используйте последнюю свою.

Использование компоненты отправки сообщений в 1С:

Объект = НОВЫЙ COMОбъект("AMQPSend.COM"); //Создаем COM  объект
Объект.Connect(ИмяСервераКролика, Логин, Пароль);// Подключаемся к серверу Кролика
Результат = Объект.Send(ИмяУзла, КлючМаршрутизации, СтрокаДанных); //Отправляем данные
Объект.Close();//Закрываем соединение к серверу Кролика

У объекта только одна функция Send. Имя узла - Exchange Кролика, КлючМаршрутизации - routingKey, СтрокаДанных - строковое представление передаваемых данных.

В случае успешной технической отправки данных функция возвращает "0", либо описание исключения в случае технической неудачи. Проверки прав на помещение данных в указанный узел у пользователя, под которым компонента подключилась к Кролику не писал.

Таким образом, отправлять 1С данные в Кролика указанному получателю мы научились. Далее пришло время получать это все оттуда. Так же на C# была написана простенькая служба, которая создает подписчиков на определенные ключи маршрутизации в определенных узлах и переправляет эти данные получателям.

Установка службы:

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\installutil <Путь к exe файлу службы>

Удаление

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\installutil /u <Путь к exe файлу службы>

Получателям 1С служба умеет отправлять данные двумя способами - в HTTP-сервис или в Web-сервис. Служба может поднимать множественное количество подписчиков на разные ключи маршрутизации и узлы, переправляя данные в http и/или web-сервис.

Пример конфигурационного файла (находится в папке с экзешником)

<consumers>
  <consumer>
    <host>[Имя сервера Кролика]</host>
    <routingKey>[Ключ маршрутизации]</routingKey>
    <exchange>[Узел Кролика]</exchange>
    <httpUrl>[URL для переправки данных]</httpUrl>
    <soapUrl>[URL для POST запроса в WEB-сервис]</soapUrl>
    <soapAction>[Функция, вызываемая в WEB-сервисе]</soapAction>
    <user>[Пользователь Кролика]</user>
    <password>[Пароль пользователя Кролика]</password>
    <prefetchCount>[Число сообщений, считываемых службой из очереди Кролика]</prefetchCount>
    <soapUrlExample>http://domain.com/base/ws/ESBExchange</soapUrlExample>
    <soapActionExample>http://domain.com/base/ws/ESBExchange/UploadData</soapActionExample>
  </consumer>
</consumers>

 

Credentials для запросов в 1С не ставил, т.к. у меня предполагается отправка все внутри сети. prefetchCount - это уже начались игры разума по вопросам распараллеливания переправки сообщений в 1С. Поднимать несколько подписчиковна одну очередь или забирать в экземпляр слушателя несколько сообщений и распараллеливать в нем - дальше бесконечное поле для ускорения и т.п. prefetchCount определяет сколько сообщений забирает на обработку подписчик себе из очереди Кролика.

В моем случае в одну очередь в день попадет до 30к сообщений - последовательно они все успешно отрабатывают, потому я оставляю этот параметр равный 1. Без создания тасков внутри подписчика увеличение данного числа ничего не даст.

Дополнительно настраивается еще один файл SOAPquery.txt:

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:ns="ns">
   <soap:Header/>
   <soap:Body>
      <ns:UploadData>
         <ns:Data>%data%</ns:Data>
      </ns:UploadData>
   </soap:Body>
</soap:Envelope>

В этот файл я добавил шаблон запроса в Web-сервис. Некрасиво, но удобно. Находить удобные библиотеки для работы с SOAP мне было лень. Текст %data% в шаблоне заменяется на передаваемые текстовые данные, потому лучше заворачивайте их в строку Base64, чтобы не заниматься экранированием и прочими радостями. Формат файла удобно получить из SoapUI, скормив ему WSDL вашего сервиса.

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

Теперь прием сообщения в 1С:

[Блок получения данных в HTTP/WEB сервисе]
[Парсинг данных и необходимые действия]

Объект = НОВЫЙ COMОбъект("AMQPSend.COM");
Объект.Connect(ИмяСервераКроликаДляОтвета, Логин, Пароль);
Результат = Объект.Send(ИмяУзлаДляОтвета, КлючМаршрутизацииДляОтвета, ДанныеСОтветом); 
Объект.Close();

В начале производим все необходимые данные в соответствии с логикой загрузки. Далее из входящих данных получаем идентификатор, данные Кролика этого пакета данных (мы ведь их передаем вместе с данными, верно?) и передаем точно так же обратно в Кролик. Теперь наша передача сообщения в другую систему выглядит как:

  1. Система 1 формирует передаваемый пакет, дополняя его данными для отправки уведомления о доставке.
  2. Система 1 отправляет его в очередь Системы 2.
  3. Система 2 принимает пакет из очереди и обрабатывает его.
  4. Система 2 отправляет подтверждение в очередь, настройки которой пришли во входящем пакете.

Таким образом, обеим системам неважно, кто и каким образом отправляет сообщение (если это важно для бизнес-логики, то эта обработка будет на стороне каждой из систем на основании входящих данных). Схема чрезвычайно легко масштабируется. В очередь/узел Системы 2 могут посылать сообщения любые другие системы и ответ в эти системы будет точно таким же, как и в Систему 1.

Так что пробуйте, видоизменяйте, унифицируйте.

К публикации приложены как есть:

  • COM компонента для отправки сообщения из 1С
  • Служба подписчиков
  • Исходники и того, и другого.

Экономика:

Потрачено - 5 вечеров свободного времени.

Получено - высвобождение 3-4 человеко часа в день, что в условиях кадрового дефицита - бесценно :)

 

PS Заранее предупрежу - я не .NET разработчик. Писал все на знаниях, оставшихся после института, и туториалах из интернета. Достигать максимального уровня абстракции не собирался. Все выложено исключительно для пробных шагов в этом направлении остальных участников сообщества. Код открыт - можно и нужно модифицировать, как угодно.

62

Скачать файлы

Наименование Файл Версия Размер
MQ Rabbit + 1С. Быстрый старт.:
.zip 2,44Mb
09.06.18
24
.zip 2,44Mb 24 Скачать

См. также

Комментарии
Сортировка: Древо
1. kraynev-navi 370 10.06.18 07:45 Сейчас в теме
Я бы все-таки обратил внимание на разграничение доступа. Нужна хотя бы минимальная защита. Любая копия базы, снятая с рабочей, начнет слать в рэббит "левые" сообщения. Сэкономленные человеко-часы будут перечеркнуты "случайными" отправками платежных документов из баз разработчиков.
2. Goleff74 130 10.06.18 10:28 Сейчас в теме
(1)
Ну, это уже на уровне кода конфигураций контролировать. Либо ключи маршрутизации создавать вида <Строка базы 1><Строка базы 2>, или наплодить несколько узлов с именами Система отправителя в виде строк этих баз, и оттуда уже ключами маршрутизации перенаправлять в узел получателя. Простор для творчества.
А еще лучше не регистрировать компоненту на сервере разработчиков :)
3. Steelvan 10.06.18 11:53 Сейчас в теме
туториал = руководство, неуч
Yakud3a; Gureev; +2 19 Ответить
6. nixel 508 10.06.18 23:44 Сейчас в теме
(3) граммар наци живёт в ЖЖ. проследуйте туда.
ZhdanovR; ktb; amon_ra; pbazeliuk; webester; UniversaLL; +6 Ответить
12. Evil Beaver 5245 13.06.18 18:47 Сейчас в теме
4. s-coder 10.06.18 20:44 Сейчас в теме
Почему я должен скачивать за мани этих стар, чтобы попробовать?
5. Goleff74 130 10.06.18 23:01 Сейчас в теме
(4)
Вы не должны
Alien_job; o.nikolaev; kote; Berckk; ABudnikov; igormiro; bsturtle; baton_pk; Evil Beaver; JohnyDeath; WizaXxX; ArchLord42; madonov; karpik666; ktb; pbazeliuk; jaroslav.h; evgefremov; 9-pm; ifal; t.v.s.; UniversaLL; +22 Ответить
7. Новиков 288 13.06.18 11:56 Сейчас в теме
Приветствую!

К Вашей цитате:
я не обнаружил сразу описания HTTP интерфейса Кролика


Не могли бы пруфом поделиться? Спасибо!
8. Goleff74 130 13.06.18 12:23 Сейчас в теме
10. Evil Beaver 5245 13.06.18 18:37 Сейчас в теме
(8) ой не, HTTP-API это прям совсем медленно, тем более, что по ссылке - администраторский API. Да, он позволяет отправлять, но это костылище. Используйте родных клиентов, работающих по протоколу AMQP. Например, наш <скрытая реклама детектед> :)
9. user634257_mryzhov 13.06.18 16:04 Сейчас в теме
В целом не видно в чем здесь выигрыш от Раббит.
30 тысяч сообщений в сутки - не является каким то запредельным параметром для стандартных файловых транспортов фтп, общая папка. Интересно менялась ли схема выгружаемых данных,обработка коллизий, обработка потери сообщений (по крайней мере не принятые пакеты хорошо бы не удалять из очереди или кидать в очередь сообщений с ошибками). Как я понял по коду компоненты, нет обработки исключений, т.е. сообщение в любом случае удаляется из очереди.
Открывает лог отправки данных в системе отправителе и смотрит в нем все статусы пакета данных (дата отправки, дата получения, ссылка на текст отправленных данных).
Проверяет логику формирования данных.
Подобную логику можно гораздо легче на стандартном обмене через файлы реализовать. А то усложняем там где ничего усложнять не требуется.
11. Evil Beaver 5245 13.06.18 18:40 Сейчас в теме
(9) дело в управлении этим хранилищем файлов. Рано или поздно, автоматизируя папку обмена и настраивая к ней доступ, вы напишете сервер очередей. Так может сразу начать с него?
Сурикат; +1 Ответить
13. user634257_mryzhov 14.06.18 16:21 Сейчас в теме
(11) На этапе когда нужен обмен между двумя базами - сервер очередей избыточен.
В описанном примере это именно такой случай - из-за применения Раббита осталось только еще больше не проработанных вопросов, которые до этого при обычном файловом обмене были решены. То есть мы существенно увеличили сложность решения (отдельный сервер очередей, внешние компоненты для обмена, ХТТП-сервис), функциональность та же, а качество хуже.

Rabbit - не серебрянная пуля:)

Я не рассматриваю случаи когда у нас сотни потребителей, распаралеленные очереди, несколько серверов очередей связанных между собой и разнородные среды для интеграции - тогда да я обеими руками за Раббит)
14. 1cProfit 25.06.18 15:49 Сейчас в теме
у кого-то есть готовая компонента для раббита ?
15. Goleff74 130 28.06.18 10:15 Сейчас в теме
(14)
Прикреплена к статье вместе с исходниками.
16. baracuda 3 26.07.18 12:36 Сейчас в теме
Правильно понимаю, что в основном это применяется для разработки сервисных шин данных? ESB?
Где еще можно применить связку?
17. Goleff74 130 26.07.18 14:13 Сейчас в теме
(16)
Например, распределение пиковой нагрузки. Пришло вам 100500 запросов в секунду и веб-сервер отказался работать. Засунули эти 100500 в очередь, сами указали сколько потоков параллельно обрабатываются из Кролика и в колбэк функцию вернули результаты запроса.
18. baracuda 3 26.07.18 15:16 Сейчас в теме
(17) ясно. спасибо за пример.
19. zarucheisky 30.07.18 11:29 Сейчас в теме
(0) ActiveMQ имеет встроенный REST API :)
Вовсе необязательно подсовывать кролика где ни попадя.
Оставьте свое сообщение