Передача больших сообщений в Biztalk через MSMQ

в 14:39, , рубрики: Песочница

По работе возникла задача: распространять справочники через Biztalk, сами справочники достаточно большие – более 300 мегабайт. Было принято решение использовать MSMQ для получения сверх больших сообщений. А теперь подробнее, что для этого потребовалось сделать.
Конечно же первое что можно сделать это погуглив найти пример на MSDN как всё это реализовать (далее я его опишу на русском совместно с изменениями), но сразу оговорюсь что у этого примера есть небольшой – нельзя настроить размер части на которые делится сообщение, что может быть необходимо для различных задач. Итак приступим.

Для разработки нам понадобится:

  • Visual Studio 2010 SP1
  • Biztalk Server 2010 SDK
  • Biztalk Server 2010 (для тестов)
  • Желание во всём разобраться

Открываем проект <Путь к Biztalk Server 2010 SDK>AdaptersUsage MSMQLarge LargeMessages.sln. Видим что решение содержит два проекта: один из них на С++.NET, второй на C#. Для начала нам нужен первый, чтобы реализовать Возможность самому выбирать размер на которое дробится наше сообщение в очереди необходимо кое-что подправить в классе. Как видно из исходного кода размер передаётся в функции:

MQSendLargeMessage(unmanagedQueueData->queueHandle, 
			&(messageData->message),
			MQ_SINGLE_MESSAGE,
			MQRTLARGE_USE_DEFAULT_PART_SIZE);

По умолчанию MQRTLARGE_USE_DEFAULT_PART_SIZE определенно равным нулю, что означает использование размера по усмотрению сервера. Для своих целей мы добавим приватную переменную dwQueuePartSize и соответственно изменим приватную функцию Init(…)

void Init(String* formatName, bool useAuthentication, DWORD dwQueuePartSize) 
		{
			this->formatName = formatName;
			this->useAuthentication = useAuthentication;
			this->dwQueuePartSize=dwQueuePartSize;
			AllocUnmanagedQueueData();
		}

Теперь она имеет дополнительный параметр отвечающий за установку размера при инициализации. Теперь нам необходимо соответствующим образом модифицировать конструкторы, которую использую эту функцию.

LargeMessageQueue(String* formatName, bool useAuthentication) 
		{
			Init(formatName, useAuthentication, 0);
		}
LargeMessageQueue(String* formatName) 
		{
			Init(formatName, false, 0);
		}

Сейчас можно добавить наш конструктор который принимает соответствующее значение:

LargeMessageQueue(String* formatName, DWORD dwQueuePartSize) 
		{
			Init(formatName, false, dwQueuePartSize);
		}
LargeMessageQueue(String* formatName, bool useAuthentication, DWORD dwQueuePartSize) 
		{
			Init(formatName, useAuthentication, dwQueuePartSize);
		}

Мы продублировали два стандартных конструктора, для того чтобы можно было устанавливать произвольный размер. Небольшое замечание: можно было бы и добавить параметр в уже объявленные конструкторы и подправить параметры Init, но мы теряем обратную совместимость библиотеки с другими решениями, которые вы возможно уже реализовали, либо используете сторонние решения основанные на этой библиотеке.
На этом этапе мы получаем рабочую библиотеку с необходимым нам функционалом. Настало время всё это протестировать на простом примере. Для этого откроем второй проект в решении, написанный на С# открываем файл App.cs и подправляем следующий фрагмент

LargeMessageQueue queue =
                new LargeMessageQueue(queueFormatName);
на
LargeMessageQueue queue =
                new LargeMessageQueue(queueFormatName, 3145728);

Теперь делаем полную сборку проекта, лучше всего предварительно сделать Build Clean.
На этом разработка заканчивается. Для теста создадим простое приложение BizTalk, котрое будет брать сообщение из очереди и складывать его в папку С:Demo.

  1. Создайте приватную очередь на локальном компьютере с именем Test, при создании необходимо выбрать параметр который указывает на поддержку очередью транзакций. Обязательно проверьте права на получение сообщений из этой очереди пользователем из под которого работает Ваш BizTalk Server
  2. Создайте папку С:Demo. Опять же обязательно проверьте права на зпись в папку для пользователя из под которого работает Ваш BizTalk Server
  3. 3. Откроем консоль администрирования Biztalk и создадим новое приложение, назовём его допустим MSMQBiztalkTest. В этом приложении создадим Send Port типа Static One-Way Send Port и назовём его MySendPort. Выбираем transport Type – FILE и соответственно настраиваем его, чтобы он складывал наши сообщения в папку C:Demo, которую мы ранее создали. Устанавливаем фильтр на этот порт со следующим значением BTS.ReceivePortName == MyReceivePort
  4. Создадим новый Receive Port типа One-way Receive Port и назовём его MyReceivePort. Для этого порта создадим новый Receive Locations типа One-way Receive Location с названием MSMQReceiveLocation. Выбираем Transport Type равным MSMQ и настраиваем на получение сообщений из нашей очереди для этого в настройках укажем Queue равной localhostprivate$test и установим Transactional в True.
  5. На этом тестовое BizTalk приложение создано, необходимо его запустить и перезапустить Biztalk сервис.

Для посылки сообщения в очередь используем приложение созданное нами ранее в VisualStudio 2010. Работает оно из командной строки и соответственно принимает два параметра параметры очереди и имя файла, который необходимо отправить.
SendLargeMessage.exe DIRECT=OS:localhostprivate$Test «C:TestDataLargeFile.xml»
В зависимости от размера файла вы сможете наблюдать его в каталоге C:Demo уже через несколько секунд и смотреть, как он постепенно растёт.
На этом всё. Если у кого-то возникли вопросы или пожелания с удовольствием отвечу на все в комментариях.
Источники:
Large Message to MSMQ

Автор: maxim_rubchenko


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js