Обмен сообщениями в Microsoft Azure, или Как общаться в облаках

  • Tutorial
Мое знакомство с облаком Azure началось еще во время практики в DataArt. На третьем месяце обучения к моему ментору Диме пришел коллега Антон и сказал, что ему нужен кто-то для маленького демонстрационного проекта. Так мы и познакомились.

Антон – человек увлеченный и очень активный, умеет вдохновлять идеями. Практика давно закончилась, через какое-то время Антон расстался с DataArt, но продолжает активно интересоваться и продвигать Microsoft Azure, часто консультирует наших коллег по Azure-технологии и предлагает поучаствовать в разных тематических событиях. В частности, он проводит разные семинары, тренинги, встречи, посвященные этому облаку, и не так давно в Киеве было создано первое в нашей стране Ukrainian Azure Community.

Это группа единомышленников, которые активно интересуются технологией, делятся полученными знаниями и общаются на тему Azure. Раз в месяц-два проходят встречи, каждая посвящена отдельной теме. Часто эти встречи проходят как раз в киевском офисе DataArt.

Темой встречи, где, в частности, выступала я, выбрали обмен сообщениями при помощи разных Azure-сервисов. Мы услышали об Azure Storage Queues, Azure Service Bus Queues, Azure Service Bus Topics & Subscriptions.

Поделюсь технической частью. Существует три типа моделей обмена сообщениями.


Рис. 1

В случае с моделью А сообщение отправляется напрямую от отправителя к получателю. Это самая простая модель, но у нее есть недостатки:
— сложно масштабировать (да-да, это ж облака!);
— легко потерять сообщения (например, получатель уходит в офлайн);
— сложно реализовать retry policy.
Из-за этих недостатков в Azure в основном используются модели Б (сообщение попадает в своеобразный брокер, получатель «забирает» его оттуда) и В (сообщение попадает в брокер, а брокер отправляет его получателю).

Azure Storage Queues

Это самая обычная очередь FIFO. Она соответствует модели Б.
Внутри одного Azure-аккаунта можно создать произвольное количество очередей с уникальными именами. Имя очереди должно быть url-friendly. Каждая очередь может содержать произвольное количество сообщений, но размер одного сообщения ограничен 64 Кб. Т. е. очередь не предназначена для обмена данными, а только для обмена задачами.
(Вопрос на подумать: а что делать, если сообщение по каким-то причинам не помещается в 64КБ? Думать в контексте Azure.)


Рис. 2

Отправка сообщения в очередь выглядит так:

// Retrieve storage account from connection string
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(_cloudConnectionString);

// Create the queue client
CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();

// Retrieve a reference to a queue
CloudQueue queue = queueClient.GetQueueReference("somecorrectqueuename");

// Create the queue if it doesn't already exist
queue.CreateIfNotExists();

string messageToSend = string.Format("message #{0}", i);

// Create a message and add it to the queue.
CloudQueueMessage message = new CloudQueueMessage(messageToSend);
queue.AddMessage(message);


Пропускная способность Azure на отправку в очередь — до 20 тыс. сообщений в секунду.
Особенность этой очереди —определенный таймаут (по умолчанию 30 секунд) на обработку одного сообщения. Т. е. при чтении сообщение не убирается из очереди, а становится невидимым для других получателей. Если сообщение было обработано корректно, его нужно явно удалить из очереди. Если же произошли ошибки чтения или другая исключительная ситуация – в общем, есть по истечению таймаута сообщение не будет явно удалено – оно опять появится в голове очереди и станет доступным для чтения другими получателями.

Корректная обработка сообщения выглядит так:

// Retrieve storage account from connection string
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(_cloudConnectionString);

// Create the queue client
CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();

// Retrieve a reference to a queue
CloudQueue queue = queueClient.GetQueueReference("somecorrectqueuename ");
while (true)
{
// Get the next message
CloudQueueMessage retrievedMessage = queue.GetMessage();

if (retrievedMessage != null)
{
//Process the message in less than 30 seconds, and then delete the message
queue.DeleteMessage(retrievedMessage);
}
else
{
Thread.Sleep(2000);
}
}


Таймаут для каждого сообщения можно выставлять свой (на стороне получателя). Сообщения могут содержать в себе только строки, которые для пересылки кодируются в base64. Кроме того, есть возможность «посмотреть» содержимое сообщения, не забирая его из очереди, можно и прочитать сообщения «пакетами» — сразу несколько.

Для работы с Azure Storage Queue предоставлено REST api, что позволяет работать с очередями независимо от платформы. Кстати, это единственная на данный момент технология мессаджинга в Azure, с которой можно работать прямо из JS.

Как видите, сервис предоставляет не очень широкую функциональность, вернее, строго определенную. Тем не менее, он дает возможность поднять вероятность доставки сообщения получателю по сравнению с пересылкой сообщений по модели А (без посредника). Такая очередь хорошо подходит для архитектур, когда получатель не всегда находится онлайн. Пример — отправитель осуществляет какую-то активность в течение дня, логирует свою деятельность в очередь, а в конце дня в сети появляется получатель, обрабатывает эту информацию, генерирует, например, отчеты и опять «засыпает» до следующего дня.

Наконец, Azure Storage Queue — самый дешевый сервис для мессаджинга в Azure.

Azure Service Bus Queues, Azure Service Bus Topics & Subscriptions

Azure Service Bus — сервис, который предоставляет несколько возможностей передачи сообщений. Принципиально их можно разделить на два типа:
  • Brokered bus — асинхронная передача сообщений; сохраняет сообщения, отправляет их, когда получатель готов их прочитать, использует два механизма: ‘queues’ и ‘topics and subscription’
  • Relayed bus — синхронная передача сообщений; сообщения нигде не сохраняются, отправляются «в среду» и, если получатель готов, он их прочитает, если нет — сообщения теряются.
  • Azure Service Bus Queues (Рис. 3) предполагает модель В (рис. 1). От Azure Storage Queues принципиально отличается тем, что сообщения из брокера отправляются к получателю, когда тот сообщает о готовности, а не наоборот. Еще есть возможность отправлять несколько сообщений за раз (с помощью транзакций). Кроме того, если Azure Storage Queues поддерживают At-Least-Once гарантию доставки, т. е. сообщения будут, как минимум, один раз прочитаны (а могут при определенных сценариях и больше), Azure Service Bus Queues поддерживают At-Least-Once At-Most-Once гарантию — значит, сообщение будет прочитано не менее и не более одного раза.



Рис. 3

Azure Service Bus Topics & Subscriptions (Рис. 4) тоже реализует модель В, но совсем по-другому.


Рис. 4

В service bus namespace создаются так называемые topics. Это можно буквально понимать как «темы». Там же создаются и подписки на темы — subscriptions. Сообщение от отправителя проходит определенный топик (отправитель решает, в какой топик отправлять сообщение) и уже в топике автоматически фильтруется и копируется в каждую подписку, которая удовлетворяет фильтру. Сообщение не хранится в топике. Если для сообщения не нашлось подходящей подписки, оно исчезает. Если нашлось несколько подходящих подписок, то оно будет скопировано в каждую из них.

Подписки создают получатели сообщений. Для каждой указывается фильтр (который может быть и пустым, это будет значить, что в подписку будут копироваться все сообщения, которые приходит в соответствующий топик). Фильтр может быть изменен без изменения подписки, при этом сообщения, которые там уже лежат, утеряны не будут, а новые будут поступать уже по обновленному фильтру.

Чтение сообщений получателем может быть организовано с помощью двух механизмов: ReceiveAndDelete и PeekLock. Первый подразумевает обычное чтение сообщения из очереди — после поступления запроса на сообщение в подписку оно отправляется получателю и удаляется из очереди. Второй механизм, как в Azure Storage Queues, предполагает какой-то таймаут на обработку сообщения. И если по его истечении не поступает подтверждение, что сообщение успешно обработано, оно опять становится видимым для других получателей.

Подробнее про Azure Storage Queues можно почитать тут.

Про Azure Service Bus Queues тут.

Сравнение Azure Storage Queues и Azure Service Bus Queues.

Про Azure Service Bus Topics & Subscriptions тут.

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

В заключение хочу отмечу, что технологии Microsoft Azure очень активно развиваются, появляются новые фичи, некоторые устаревают, поэтому актуальную информацию всегда лучше проверять на официальном сайте.

Автор: Анастасия Белокурова, .NET Developer
  • +12
  • 7,4k
  • 2
DataArt
162,00
Технологический консалтинг и разработка ПО
Поделиться публикацией

Похожие публикации

Комментарии 2

    +1
    Ответ на ваш вопрос — если сообщение не помещается в 64Кб — стоит задуматься над архитектурой и тем что вам слишком много данных нужно передавать. Сообщение это больше команда — краткое указание. А по факту — сложите ваши большие данные в блоб и в сообщение засуньте ссылку по которой блоб можно скачать или его ID.

    И еще — 20 000 сообщений в секунду для очереди — это не опечатка? вот тут msdn.microsoft.com/library/azure/hh697709.aspx говорят только про 2000 сообщений в секунду на очередь, 20 000 это вроде предел на весь аккаунт…
      0
      Да, Вы правы, это опечатка. 2 тыс сообщений в секунду для одной очереди (http://azure.microsoft.com/en-us/documentation/articles/storage-performance-checklist/#subheading39) и 20 тыс на аккаунт (http://azure.microsoft.com/en-us/documentation/articles/storage-scalability-targets/).

      Согласна с Вами по поводу архитектуры, но хотелось услышать именно вторую часть Вашего ответа:)

    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.