Здравствуйте.
Описанные ниже мысленные изыскания были навеяны статями сильвер булетов и прочих товарищей по использованию очередей на основе RabbitMQ. Описывать, что, как и зачем использовать этот брокер мессенджер не вижу смысла - в предыдущих статьях все хорошо описано. Здесь я опишу сугубо практику применения.
Причина использования очередей - зоопарк систем на новом месте работы, обменивающихся друг с другом информацией всевозможными спосособами. Как правило, способами медленными не информативными и отнимающими тонны рабочего времени отдела на собственную поддержку.
Основной обмен происходил файлами через файлопомойку без какого-либо оповещения об обработке входящих данных и т.п. Зачастую получалась ситуация, что данные отправлены, что-то пошло не так, данные не получены системой получателем, но система отправитель об этом ни сном ни духом. В результате получаем бесконечный поток писем в поддержку "Где наши платежи/заказы/etc?! В рознице деньги оприходовали/заказ провели,, а на сайт они не попали" и т.п. На диагностику проблемы уходило безумное количество времени, потому что, чтобы понять причину сотрудник поддержки:
- Смотрел лог отправки в системе отправителе.
- Проверял, что файла нет в папке получателе. (данные не стоят в очереди)
- Проверял, что файл есть в архивной папке системы получателя (данные получены и обработаны)
- Проверял данные самого файла.
- Проверял логику формирования данных.
И это на каждое письмо. Теперь:
- Открывает лог отправки данных в системе отправителе и смотрит в нем все статусы пакета данных (дата отправки, дата получения, ссылка на текст отправленных данных).
- Проверяет логику формирования данных.
В итоге получаем значительную экономию времени. Думаю, у каждого таких примеров наберется немало.
Итак, выбор пал на 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.
- Система 2 принимает пакет из очереди и обрабатывает его.
- Система 2 отправляет подтверждение в очередь, настройки которой пришли во входящем пакете.
Таким образом, обеим системам неважно, кто и каким образом отправляет сообщение (если это важно для бизнес-логики, то эта обработка будет на стороне каждой из систем на основании входящих данных). Схема чрезвычайно легко масштабируется. В очередь/узел Системы 2 могут посылать сообщения любые другие системы и ответ в эти системы будет точно таким же, как и в Систему 1.
Так что пробуйте, видоизменяйте, унифицируйте.
К публикации приложены как есть:
- COM компонента для отправки сообщения из 1С
- Служба подписчиков
- Исходники и того, и другого.
Экономика:
Потрачено - 5 вечеров свободного времени.
Получено - высвобождение 3-4 человеко часа в день, что в условиях кадрового дефицита - бесценно :)
PS Заранее предупрежу - я не .NET разработчик. Писал все на знаниях, оставшихся после института, и туториалах из интернета. Достигать максимального уровня абстракции не собирался. Все выложено исключительно для пробных шагов в этом направлении остальных участников сообщества. Код открыт - можно и нужно модифицировать, как угодно.