Построение гибридных приложений в облаке на платформе Windows Azure patterns & practices



Pdf просмотр
страница24/33
Дата28.11.2016
Размер8.44 Mb.
Просмотров6414
Скачиваний0
1   ...   20   21   22   23   24   25   26   27   ...   33
RequiresSession. У всех сообщений, помещаемых в эту очередь, свойство SessionId должно иметь значение строкового типа. Значение, хранящееся в этой строке, идентифицирует сеанс, и все сообщения с одним и тем же значением свойства SessionId считаются частью одного сеанса. Обратите внимание, что несколько отправителей могут посылать сообщения с одним и тем же идентификатором сеанса, в этом случае все соответствующие сообщения рассматриваются как один сеанс.
Получатель, который приступает к обработке событий сеанса, вызывает метод
AcceptMessageSession объекта QueueClient. Этот метод создает объект сеанса, и получатель может использовать его для извлечения сообщений из сеанса, как из обычной очереди. Метод
AcceptMessageSession«прикрепляет» к получателю сообщения в очереди, которые составляют один сеанс, и скрывает их от всех других получателей. Другой получатель, вызывающий метод
AcceptMessageSession, получит сообщения из следующего доступного сеанса. На рисунке 14 показаны два отправителя, которые посылают сообщения с различными идентификаторами сеанса, каждый отправитель генерирует свой собственный сеанс. Получатели каждого сеанса обрабатывают только те сообщения, которые относятся к этому сеансу.
Рисунок 14
Использование сеансов для группировки сообщений
Вы также можете организовать дуплексные сеансы, если получатель должен отправить набор сообщений в качестве ответа. Для этого в свойстве ReplyToSessionId ответного сообщения перед отправкой нужно установить значение, указанное в свойстве SessionId принятого сообщения.
Отправитель может создавать свои собственные сеансы и при помощи идентификатора сеанса сопоставлять сообщения в сеансе ответов с оригинальными запросами.
Сеанс сообщений может включать в себя информацию о состоянии сеанса, которая сохраняется вместе с сообщениями в очереди. Вы можете использовать эту информацию для отслеживания операций, выполненных в рамках сеанса, а также для создания простого конечного автомата на стороне получателя сообщений. Когда получатель извлекает сообщение из очереди, он может сохранить информацию о выполненных операциях при обработке сообщения как информацию о состоянии сеанса и поместить эти данные обратно в очередь. Если на стороне получателя происходит сбой или он неожиданно завершает свою работу, другой экземпляр может подключиться к сеансу, получить информацию о его состоянии и продолжить обработку сообщений. Этот сценарий показан на рисунке 15.
Мнение Маркуса
Используйте методы GetState и SetState объекта MessageSession, чтобы извлечь и обновить информацию о состоянии сеанса сообщений.
Отправитель
А
Получатель для сеанса А
Отправитель
Б
Получатель для сеанса Б
Сообщения сеанса Б
Сообщения сеанса А
Отправка сообщений для сеанса Б
Отправка сообщений для сеанса А

295
Рисунок 15
Извлечение и сохранение информации о состоянии сеанса сообщений
Вполне возможно, что сеанс будет бесконечным, сообщения будут идти непрерывным потоком через различные (иногда достаточно продолжительные) промежутки времени.
В таком случае получатель сообщений должен быть готов переходить в спящий режим на определенный срок. При получении нового сообщения в рамках сеанса, другой процесс, контролирующий систему, может инициировать выход получателя из спящего режима, чтобы тот продолжил обработку.

Отправитель должен послать одно или несколько сообщений в очередь единым блоком.
Если некоторые операции завершились неудачно, то ни одно из сообщений не подлежит
отправке, и все они должны быть удалены из очереди.
Самый простой способ отправки нескольких сообщений единым блоком — с помощью локальной транзакции. Вы можете инициировать локальную транзакцию, создав объект
TransactionScope. Это программная конструкция, которая определяет границы для множества задач, составляющих одну транзакцию.
Чтобы отправить группу сообщений в одной транзакции, необходимо инициировать операцию отправки для каждого сообщения в рамках одного и того же объекта TransactionScope. При этом сообщения просто помещаются в буфер и не отправляются до завершения транзакции.
Для того чтобы все сообщения были отправлены, вы должны успешно завершить транзакцию.
Если транзакция не завершена, ни одно сообщение не будет отправлено, и все они удаляются из очереди. Более подробная информация о классе TransactionScope представлена в статье
«TransactionScope Class» на сайте MSDN: http://msdn.microsoft.com/en- us/library/system.transactions.transactionscope.aspx
Если вы отправляете сообщения в асинхронном режиме (рекомендуемый подход), скорее всего, вам не потребуется использовать объект TransactionScope. Обратите внимание, что если вы используете операции из других транзакционных источников, таких как базы данных SQL Server, то эти операции не могут быть выполнены в рамках одного и того же объекта TransactionScope, поскольку диспетчер ресурсов, который упаковывает очереди шины интеграции, не может использовать операции совместно с другими диспетчерами ресурсов.
Мнение Маркуса
Если вы попытаетесь использовать объект TransactionScope для выполнения локальных транзакций, в которых задействованы очередь шины интеграции и другие диспетчеры ресурсов, ваше приложение выдаст исключение.
Отправитель
Получатель для сеанса
Сообщения сеанса
Состояние сеанса сообщений
Получатель обновляет состояние сеанса каждый раз после приема сообщения

296
В подобных сценариях можно реализовать свой псевдотранзакционный механизм, основанный на ручном обнаружении ошибок, логике для повторных попыток и устранения дубликатов сообщения (dedupe) очереди шины интеграции.
Чтобы задействовать механизм устранения дубликатов, отправитель должен каждому сообщению, которое он помещает в очередь, присвоить уникальный идентификатор. Если два сообщения в одной очереди имеют одинаковые идентификаторы, они будут считаться идентичными, и логика устранения дубликатов удалит второе сообщение. Используя эту функцию в случае возникновения сбоя в работе своей бизнес-логики, приложение-отправитель может просто попытаться повторно отправить сообщение в процессе обработки отказа или повтора. Если у сообщения, которое было успешно послано ранее, появляются дубликаты, они будут удалены, и получатель увидит только первое сообщение. Такой подход гарантирует, что сообщение всегда будет отправлено, по крайней мере, один раз (при условии наличия у отправителя действующего подключения к очереди), но при этом будет достаточно сложно удалить сообщение, если алгоритм обработки сбоев в бизнес-логике определит, что это сообщение не подлежало отправке.
Мнение Маркуса
Функция обнаружения дубликатов активируется путем присваивания значения «true» свойству RequiresDuplicateDetection при создании очереди. Изменить значение этого свойства у существующей очереди невозможно. Кроме того, свойству
DuplicateDetectionHistoryTimeWindow необходимо присвоить значение TimeSpan, таким образом указывается период, в течение которого дубликаты сообщений с данным идентификатором удаляются. Если сообщение с этим идентификатором появляется по истечении указанного периода, оно будет помещено в очередь на доставку.

Получатель извлекает одно или несколько сообщений из очереди, и снова в рамках
транзакционной операции. Если завершить транзакцию не удалось, то все сообщения
в очереди должны быть заменены, чтобы их снова можно было прочитать.
Получатель может извлекать сообщения из очереди шины интеграции в одном из двух режимов: ReceiveAndDelete и PeekLock. В режиме ReceiveAndDelete сообщения удаляются из очереди сразу после прочтения. В режиме PeekLock сообщения из очереди не удаляются, но после прочтения они блокируются, чтобы предотвратить их извлечение другим параллельным получателем, который должен получить следующее доступное незаблокированное сообщение.
Когда получатель успешно завершает обработку сообщения, он может вызвать его метод
Complete, который удалит это сообщение из очереди. Если сообщение не удается обработать, получатель может вызвать метод Abandon, чтобы снять блокировку и оставить сообщение в очереди. Такой подход позволяет выполнять асинхронный прием сообщений.
Мнение Маркуса
Режим приема сообщений ReceiveAndDelete обеспечивает лучшую производительность, чем режим PeekLock, однако режим приема PeekLock гарантирует максимальную безопасность. В режиме ReceiveAndDelete, в случае возникновения сбоя в работе получателя после прочтения сообщения, это сообщение будет потеряно. В режиме PeekLock неудачное выполнение операции получения или обработки приведет к тому, что сообщение будет отменено и возвращено обратно в очередь, где его можно будут снова прочитать.

297
По умолчанию очередь шины интеграции работает в режиме приема PeekLock.
Как и в случае с отправкой сообщений, их прием в режиме PeekLock может выполняться синхронно в рамках локальной транзакции, поскольку транзакция не пытается задействовать возможности дополнительных диспетчеров ресурсов. Для этого необходимо создать объект
TransactionScope. Если транзакцию не удалось завершить успешно, все полученные и прочитанные сообщения, имеющие отношение к объекту TransactionScope, будут возвращены в очередь.
Мнение Маркуса
Локальные транзакции поддерживаются только в режиме PeekLock, в режиме
ReceiveAndDelete это невозможно.

Получатель должен проанализировать следующее сообщение в очереди, но извлекать
его из очереди он должен только в том случае, если это сообщение предназначено для
него.
В данном случае получатель может извлечь сообщение из очереди в режиме PeekLock и скопировать его в локальный буфер с целью анализа. Если сообщение предназначено не ему, получатель может быстро вызвать метод Abandon и сделать это сообщение доступным для другого получателя.
Если сообщение содержит конфиденциальные сведения и должно быть прочитано только конкретным получателем, отправитель может зашифровать тело сообщения с помощью ключа, известного только авторизованному получателю. Отправитель может указать нужного получателя в свойстве To сообщения с помощью идентификатора. Свойства сообщения не зашифрованы, поэтому любой получатель может извлечь сообщение, но если он не распознает адрес в свойстве To, возможно, у него нет нужного ключа для расшифровки содержимого сообщения, поэтому сообщение будет отклонено и оставлено для соответствующего получателя.

298
Если указан адрес другого получателя, то
Рисунок 16
Использование режима PeekLock и шифрования с целью анализа сообщений без
извлечения их из очереди
Мнение Джаны
В качестве альтернативного подхода рекомендуем рассмотреть возможность использования топика шины интеграции с отдельной подпиской для каждого получателя. Однако подписками будет достаточно сложно управлять при наличии большого количества получателей, или когда их количество постоянно меняется.
Рекомендации по отправке и приему сообщений с использованием очередей шины
интеграции
Вы можете разработать логику приложения, которое будет отправлять и принимать сообщения, используя несколько различных технологий.

Можно использовать интерфейсы API очереди шины интеграции в Windows Azure SDK.
Дополнительная информация и хорошие практические примеры для данного подхода приведены в статье «Best Practices for Leveraging Windows Azure Service Bus Brokered
Messaging API» на портале MSDN: http://msdn.microsoft.com/en- us/library/hh545245(v=VS.103).aspx

Вы можете использовать привязки очереди шины интеграции для подключения к очереди из клиентских приложений и служб WCF. Дополнительная информация представлена
Шифровальный ключ для получателя А
Сообщение, зашифрованное при помощи ключа для получателя А
Сообщение, зашифрованное при помощи ключа для получателя Б
- Сообщение получено в режиме PeekLock.
- Адрес получателя проанализирован.
- Если указан адрес другого получателя, отклонить сообщение.
- Если адрес получателя соответствует, расшифровать тело сообщения при помощи ключа.
Шифровальный ключ для получателя Б
Дешифровальный ключ для получателя А
Дешифровальный ключ для получателя Б
Отправитель
Получатель А
Получатель Б
To: Получатель А
Зашифрованные
данные сообщения
To: Получатель Б
Зашифрованные
данные сообщения

299 в статье «How to: Build an Application with WCF and Service Bus Queues» на сайте http://msdn.microsoft.com/en-us/library/windowsazure/hh243674.aspx

Если вы создаете приложения, которые подключаются к очереди шины интеграции с использованием технологии, которая не поддерживает Windows Azure SDK, вы можете использовать интерфейс HTTP REST, предоставляемый шиной интеграции.
Асинхронная отправка и прием сообщений
При использовании Windows Azure SDK вы можете создавать приложения, которые будут отправлять и принимать сообщения при помощи классов MessageSender и MessageReceiver в пространстве имен
Microsoft.ServiceBus.Messaging. Эти типы предоставляют доступ к операциям по обмену сообщениями, которые рассматривались ранее в настоящем приложении. Основные функции для отправки и получения сообщений вызываются через методы Send и Receive данных типов. Однако эти операции являются синхронными. Например, метод Send класса MessageSender ожидает завершения операции отправки, аналогичным образом метод Receive класса MessageReceiver ждет, пока сообщение не будет доступно или пока не истечет указанный период. Помните, что эти методы в действительности представляют собой только фасады для серии запросов HTTP REST, а также что очередь шины интеграции является удаленной службой, доступ к которой осуществляется через Интернет. Кроме того, ваше сообщение должно учитывать следующее:

Операции отправки и получения могут выполняться сколь угодно долго, и ваше приложение не должно блокировать процесс ожидания их завершения.
Класс MessageSender предоставляет доступ к асинхронной версии метода Send, а класс
MessageReceiver — к асинхронной реализации метода Receive через методы
BeginSend/EndSend и BeginReceive/EndReceive соответственно. Эти методы лучше использовать вместо их синхронных аналогов. Эти методы соответствуют стандартной асинхронной модели, реализованной средствами платформы .NET Framework.
Аналогичные вопросы возникают в связи с другими операциями, такими как определение существования очереди, создание и удаление очередей, подключение к очереди и запрос длины очереди. Поэтому вы должны выполнять эти операции в соответствии с тем же надежным асинхронным подходом.
Вы также можете использовать класс QueueClient в пространстве имен
Microsoft.ServiceBus.Messaging для подключения к очереди, отправки и получения сообщений. Тип QueueClient — это абстрактный класс, который реализует расширенный набор функций, доступных в классах MessageSender и MessageReceiver.
Пакет Windows Azure SDK предоставляет дополнительные типы для отправки сообщений в топики (TopicClient) и получения сообщений из подписок
(SubscriptionClient). Однако классы MessageSender и MessageReceiver абстрагируют различия между этими типами. Например, если вы используете MessageSender для отправки и получения сообщений при помощи очередей, вы можете перейти к использованию топиков, и при этом потребуется минимальная доработка кода.
Аналогичным образом объект MessageReceiver позволяет извлекать сообщения из очереди и подписки при помощи одного и того же кода.
Однако прежде чем изменять весь существующий код, чтобы использовать объекты
MessageSender и MessageReceiver, учтите, что не все функции, реализованные при помощи типов QueueClient, TopicClient и SubscriptionClient, доступны в классах

300
MessageSender и MessageReceiver. Например, класс MessageReceiver не поддерживает сеансы.

Отправитель может публиковать сообщения в любое время, а получателю необходимо ожидать сообщения в более чем одной очереди.
Есть несколько возможных решений этой проблемы, но общепринятые подходы связаны с использованием потоков или задач для ожидания сообщений из каждой очереди, и когда сообщение появляется, система генерирует событие. Приложение, которое получает это событие, сможет затем обработать сообщение. Например, вы можете определить метод async, который использует оператор await, предоставляемый языком Visual C#, чтобы создать серию задач, которые будут ждать сообщений из всех очередей, и в случае их появления генерировать события. Затем вы можете использовать какой-либо фреймворк, например Microsoft Reactive
Extensions, чтобы получать эти события и обрабатывать сообщения по мере их появления.
Если получатель должен обрабатывать несколько сообщений, составляющих бизнес- операцию, вы можете оптимизировать процесс получения с помощью функции упреждающей загрузки в классе QueueClient.
По умолчанию объект QueueClient вызывает метод Receive, при этом из очереди извлекается только следующее доступное сообщение. Тем не менее вы можете задать свойству PrefetchCount объекта QueueClient положительное целочисленное значение, и метод Receive извлечет указанное количество сообщений из очереди
(если они имеются в наличии). Сообщения помещаются в локальный буфер приложения-получателя, после чего они больше не доступны для других получателей.
Метод Receive затем возвращает первое сообщение из своего буфера. Последующие вызовы метода Receive позволяют получить из буфера все оставшиеся сообщения, когда буфер опустошается, операция Receive извлекает следующую группу сообщений из очереди в буфер. Такой подход позволяет эффективнее использовать пропускную способность сети за счет увеличения промежутка времени, необходимого для получения первого сообщения. Тем не менее все последующие сообщения будут получены значительно быстрее.
На сообщения, подлежащие предварительной загрузке, распространяется та же семантика времени ожидания, которая действует для небуферизованных сообщений.
Если сообщения не будут обработаны в течение периода ожидания, который начинается с момента получения группы сообщений из очереди, то предполагается, что в приложении-получателе произошел сбой, и сообщения будут возвращены в очередь. Поэтому, если вы используете функцию упреждающей загрузки, то должны помещать в буфер такое количество сообщений, которое получатель может принять и обработать в течение установленного периода.

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

301 должны обрабатывать ситуацию отмены, чтобы любые фоновые потоки можно было надлежащим образом остановить, освободив ресурсы, используемые в процессе обмена сообщениями.
После извлечения сообщения из очереди его можно прочитать, воспользовавшись методом
GetBody класса BrokeredMessage. Этот метод выполняет десериализацию тела сообщения.
Десериализация данных осуществляется только один раз. Этот важный фактор необходимо учитывать в процессе работы над логикой для обработки ошибок. Вам не удастся вызвать метод
GetBody еще раз в отношении одного и того же сообщения (например, внутри обработчика исключений). Поэтому, если вам потребуется повторный доступ к данным в теле сообщения, вы должны сохранить эти данные в подходящий объект и затем использовать его.
Планирование, истечение срока действия и отсрочка сообщений
По умолчанию, когда отправитель посылает сообщение в очередь, оно сразу же становится доступным для извлечения и обработки получателем. Тем не менее вы можете сделать так, чтобы сообщение оставалось невидимым в течение определенного периода после его появления в очереди. Этот метод полезен для планирования сообщений, которые необходимо обработать через некоторое время, например, если данные должны быть опубликованы только после полуночи. Чтобы определить, когда сообщение должно появиться в очереди и стать доступным для обработки, установите свойство
ScheduledEnqueueTimeUtc объекта BrokeredMessage.
Когда отправитель посылает сообщение в очередь, оно может оставаться там в течение длительного периода времени, прежде чем получатель его примет. Сообщение может иметь срок действия, по истечении которого информация в сообщении теряет актуальность. В этом случае, если сообщение не было получено, оно должно без уведомления удаляться из очереди. Для этого необходимо настроить свойство TimeToLive объекта BrokeredMessage, когда отправитель посылает сообщение.
В некоторых случаях приложению не требуется обрабатывать следующее из доступных сообщений, оно может пропустить это сообщение, получить следующее и затем вернуться к пропущенному сообщению.
Для этого нужно отложить сообщение, воспользовавшись методом Defer класса BrokeredMessage. Этот механизм можно использовать в том случае, когда приложение получает сообщения в режиме PeekLock.
Метод Defer оставляет сообщение в очереди, но блокирует его, делая недоступным для других получателей. В назначенное время приложение может вернуться к отложенному сообщению, выполнить его обработку, а затем вызвать метод Complete или Abandon, как было описано ранее в настоящем приложении. В случае, если сообщение уже не актуально или не действительно во время его обработки, приложение может пометить его как недоставленное. Обратите внимание, что если происходит сбой в работе приложения, блокировка снимается, и сообщение становится доступным в очереди. Вы можете регулировать продолжительность блокировки при помощи свойства LockDuration в момент создания очереди.
Рекомендации по защите очередей шины интеграции
Очереди шины интеграции предоставляют инфраструктуру обмена сообщениями для бизнес- приложений. Они создаются и находятся под управлением платформы Windows Azure в облаке.
Поэтому они надежны и устойчивы. Как только отправитель поместил сообщение в очередь, оно будет оставаться там, пока не будет получено, или пока не истечет срок его действия.
Очередь шины интеграции хранится в пространстве имен шины интеграции с уникальным идентификатором URI. Вы создаете этот идентификатор при создании пространства имен, структура URI аналогична описанной в разделе «Модель безопасности службы Windows Azure Service Bus Relay» ранее в данном приложении. Используя данный идентификатор URI, приложение создает экземпляр объекта

302
MessagingFactory. Объект MessagingFactory затем можно использовать для создания объекта
MessageSender или MessageReceiver, который подключается к очереди.
Пространство имен шины интеграции формирует контекст для защиты очереди, доступ к пространству имен, в котором размещена ваша очередь, следует предоставлять только прошедшим аутентификацию отправителям и получателям. Вы можете защитить пространство имен с помощью службы ACS способом, подобным описанному в разделе «Рекомендации по защите службы Windows Azure Service Bus Relay» ранее в данном приложении, за исключением того, что домашняя область приложения доверенного участника определяется идентификатором URI пространства имен шины интеграции, к которому добавляется имя очереди, топика или подписки шины интеграции (например, http://treyresearch.servicebus.windows.net/orderstatusupdatequeue), а не адрес службы WCF.
Вы можете создать группу правил ACS для данного URI и присвоить типу утверждений

Каталог: download
download -> Составление простейшей программы в среде lego education. Запуск модели «Обезьянка барабанщица», «Рычащий лев», «Автомобиль»
download -> Функциональные части компьютера, история развития, базовая конфигурация
download -> Компьютер: друг или враг?
download -> Лекция №2 «Теоретические основы игры дошкольника» Зарубежные и отечественные теории игры
download -> Доклад муниципальное образовательное
download -> Литература для воспитанников стр. Приложения стр
download -> Министерство здравоохранения Республики Беларусь
download -> Игра как средство активизации познавательной активности учащихся в ходе изучения темы Алгоритмизация и программирование


Поделитесь с Вашими друзьями:
1   ...   20   21   22   23   24   25   26   27   ...   33


База данных защищена авторским правом ©nethash.ru 2019
обратиться к администрации

войти | регистрация
    Главная страница


загрузить материал