Диссертация (1148251), страница 18
Текст из файла (страница 18)
РЕГИСТРАЦИЯ СЛУШАТЕЛЯ В КОНФИГУРАЦИОННОМ ФАЙЛЕ АСПЕКТА4.2 Определение в аспекте стратегии реакции на исключенияКак правило, приложения в облачной среде работают с распределеннымикомпонентами и сервисами: СУБД, облачное хранилище, распределенный кэш,сервисная шина и т.п. Несмотря на то, что облачный провайдер поддерживаетдостаточно высокий уровень доступности своих сервисов, всегда возможныотказы при доступе к ним из-за неверных настроек, ошибок при обновлении ПО,сетевых проблем. В случае собственных компонентов пользователя, развернутыхна разных серверах, ситуация усугубляется ещё и возможными утечкамиресурсов, программными ошибками и повышенной непрогнозируемой нагрузкой.В любом случае, при обращении к удаленному сервису нельзя рассчитывать наего корректный ответ и необходимо проводить обработку исключений.Одной из распространенных стратегий при вызове удаленного сервисаявляется паттерн “Предохранитель” (Circuit Breaker) [124].
В повседневной жизниэлектрический предохранитель пропускает ток до тех пор, пока напряжение вцепи укладывается в допустимые пределы и разрывает цепь при превышении97допустимого уровня. После устранения неисправности предохранитель включаютвручную. Аналогичным образом можно представить работу простейшегопрограммного “предохранителя”, который контролирует доступ к удаленномуметоду. Если при обращении к нему нет проблем, то предохранитель “открыт” идопускает последующий вызов. Как только этот вызов приводит к исключению,предохранитель “закрывается” на заданный интервал времени и перенаправляетвызовы к запасным методам.
Тем самым сокращается количество запросов кудаленному компоненту, который, возможно, и так испытывает перегрузку.Предположим, что у нас есть удаленный метод с сигнатурой stringUnreliableService.GetContent(). Тогда вместо него можно вставить вызов действияаспекта, в котором будет проверяться его доступность, проверка таймаута“закрытия” и переадресация вызова запасному методу. Запасной метод затемможет вызвать другой удаленный компонент, обратиться к кэшу или вернутьзначения по умолчанию.class SimpleCircuitBreakerAspect : Aspect {static DateTime ? errorTime = null;//Таймаут, в течение которого предохранитеь будет закрытstatic readonly int resetTimeoutInMilliseconds = 1000;}[AspectAction("%instead %call *UnreliableService.GetContent")]public static string GetContentSafe() {//Если errorTime.HasValue, то предохранитель закрыт.if (errorTime.HasValue)//Если ещё не истек таймаут с момента последнего неуспешного вызоваif ((DateTime.Now - errorTime.Value).TotalMilliseconds <resetTimeoutInMilliseconds)return GetAnotherContent(); // Вызывается запасной методtry {//Проверяем доступность целевого методаstring result = (TargetMemberInfo asMethodInfo).Invoke(TargetObject, null);//Исключения не было, открываем предохранительerrorTime = null;return result;}catch (Exception) {//Закрываем предохранитель, запомнив время сбоя.errorTime = DateTime.Now;//Вызываем запасной методreturn GetAnotherContent();}}//Запасной вариант действий при сбоеprivate static string GetAnotherContent() {return "Service is busy";}ЛИСТИНГ 35.
АСПЕКТ ДЛЯ РЕАЛИЗАЦИИ ПАТТЕРНА “ПРЕДОХРАНИТЕЛЬ”98Следует отметить, что данный аспект сильно связан с целевым методом,поскольку запасные методы у каждого целевого метода должны быть свои. Этовынуждает писать отдельный аспект к каждому ненадежному удаленному методу.Ситуациюможноулучшить,воспользовавшисьпаттерном“Абстрактнаяфабрика”, когда решение о создании объекта с запасным методом делегируетсяотдельной фабрике. Таким образом, запасные методы конвертируются в классыреализующие определенный интерфейс, созданием их объектов занимаетсяфабрика (принимая аргументом сигнатуру целевого метода), а аспект будетуниверсальным.4.3 Кэширование в аспекте результатов операций, сессии и ответасервераМеханизмкэшированияпозволяетаспектамповыситьобщуюпроизводительность для сервисов, выполняющих длительные вычисления иливыбирающих редко обновляющиеся данные из базы данных.
В зависимости отпотребностей, облачная инфраструктура Microsoft Azure располагает сервискэширования в оперативной памяти запущенных ролей, в выделенной роликлиента (In-Role Caching) или же в распределенном кэше (Azure Managed CacheService). Для того, чтобы переключиться с одного типа кэша на другой,необходимо лишь внести изменения в конфигурационные файлы. С помощьюAspect.NET можно создать проект аспекта, в который средствами менеджераNuget установить пакет Windows Azure Caching, а затем написать аспект,перехватывающий вызов целевых методов и сохраняющий их результаты в кэшеAzure. Во время установки Windows Azure Caching в список зависимостейаспектного проекта будут добавлены как ссылки на служебные сборки, так идополнительные секции в конфигурационные файлы аспекта [24].
Таким образом,пользователю необходимо написать логику кэширования в аспекте для каждогоцелевого метода, уточнить настройки в его web.config, а компоновщик99Aspect.NET подменит вызовы целевых методов и применит к TargetWeb.configцелевого проекта изменения из аспектного web.config.Например, пусть в целевом классе DBFacade есть метод loadProduct(int id),который возвращает объект типа Product загруженный из базы данных. Еслицелевой метод удовлетворяет “принципу единственной обязанности” (SRP), тогдаон не занимается кэшированием полученного результата. В свою очередь,кэширование — это сквозная функциональность и имеет смысл выделить её вдействие аспекта:class CachedDBFacade : Aspect {//Кэш будет создан согласно настройкам web.config в секции “default”static Microsoft.ApplicationServer.Caching.DataCache cache = newMicrosoft.ApplicationServer.Caching.DataCache("default");}[AspectAction("%instead %call *DBFacade.loadProduct(int))")]static public Product loadCachedProduct(int id) {Product cachedProduct = (Product) cache.Get(“Product” + id);if (cachedProduct == null) {cachedProduct = DBFacade.loadProduct(id);cache.Put(“Product” + id, cachedProduct);}return cachedProduct;}ЛИСТИНГ 36.
КЭШИРОВАНИЕ, ВЫДЕЛЕННОЕ В АСПЕКТСодержимое web.config аспектного проекта, которое приведено ниже,создано автоматически при установке In-Role Windows Azure Caching иопределяет как расположение, так и стратегию облачного кэша:100<configSections><!-- Existing sections omitted for clarity. --><section name="dataCacheClients"type="Microsoft.ApplicationServer.Caching.DataCacheClientsSection,Microsoft.ApplicationServer.Caching.Core"allowLocation="true"allowDefinition="Everywhere" /><sectionname="cacheDiagnostics"type="Microsoft.ApplicationServer.Caching.AzureCommon.DiagnosticsConfigurationSection,Microsoft.ApplicationServer.Caching.AzureCommon"allowLocation="true"allowDefinition="Everywhere" /></configSections><dataCacheClients><dataCacheClient name="default"><autoDiscover isEnabled="true" identifier="[cache cluster role name]" /><!--<localCache isEnabled="true" sync="TimeoutBased" objectCount="100000" ttlValue="300"/>--></dataCacheClient></dataCacheClients><cacheDiagnostics><crashDump dumpLevel="Off" dumpStorageQuotaInMB="100" /></cacheDiagnostics>ЛИСТИНГ 37.
ИЗМЕНЕНИЯ В WEB.CONFIG АСПЕКТНОГО ПРОЕКТАДля того, чтобы бесшовно применить эти настройки к целевому проекту,необходимо переименовать его web.config в TargetWeb.config и прописать всобытия предкомпиляции аспектного проекта соответствующие команды израздела 4 главы 3.Дополнительно в облачном кэше можно хранить объекты веб-сессии, вкоторой хранятся все данные клиента веб-приложения. Традиционно веб-сессиясохранялась в оперативной памяти сервера, а также в локальной или удаленнойбазе данных.
Однако в первом случае сессия теряется при перезагрузке сервера,во втором — при его потере, а третий привносит дополнительные накладныерасходы к каждому запросу. Производительность облачного кэша существенновыше реляционной базы данных, поэтому имеет смысл переключиться нахранение объектов сессии в нем. Если пакет Windows Azure Caching ужеустановлен, то включить сохранение сеанса в In-Role кэше можно следующейсекцией в web.config аспектного проекта:101<system.web><sessionState mode="Custom" customProvider="AFCacheSessionStateProvider"><providers><add name="AFCacheSessionStateProvider"type="Microsoft.Web.DistributedCache.DistributedCacheSessionStateStoreProvider,Microsoft .Web.DistributedCache"cacheName="default"dataCacheClientName="default"/></providers></sessionState></system.web>ЛИСТИНГ 38.
ВКЛЮЧЕНИЕ АСПЕКТОМ СОХРАНЕНИЯ СЕАНСА В IN-ROLE КЭШЕСледующее средство повышения производительности веб-приложения —это кэширование http-ответа сервера. Например, можно настроить кэшированиестраницы в течение 60 сек., и тогда IIS-сервер будет отправлять один и тот жекэшированный ответ всем запросам в течение этих 60 сек., освобождая веб-рольот их обработки [48]. Если изначально веб-страница (напр.
Default.aspx)допускает такое кэширование, но в целевом проекте оно отсутствует, то следуетпри загрузке страницы (в методе Page_Init()) настроить объект Response.Cache:[ReplaceBaseClass]class OutputCacheDefaultPage : _Default {protected void Page_Init(object sender, EventArgs e) {base.Page_Init(sender, e);Response.Cache.SetExpires(DateTime.Now.AddSeconds(60));Response.Cache.SetCacheability(HttpCacheability.Public);}}ЛИСТИНГ 39.
АСПЕКТ ДЛЯ КЭШИРОВАНИЯ HTTP-ОТВЕТА СЕРВЕРАВ этом случае кэш результата страницы будет храниться в оперативнойпамяти веб-роли, которая обрабатывает запрос. Теперь осталось повысить еёнадежность и перенести кэш в In-Role облачное хранилище. Это производится спомощью следующей секции в web.config аспектного проекта:<caching><outputCache defaultProvider="AFCacheOutputCacheProvider"><providers><add name="AFCacheOutputCacheProvider"type="Microsoft.Web.DistributedCache.DistributedCacheOutputCacheProvider,Microsoft .Web.DistributedCache"cacheName="default"dataCacheClientName="default" /></providers></outputCache></caching>ЛИСТИНГ 40. ИЗМЕНЕНИЯ В WEB.CONFIG АСПЕКТНОГО ПРОЕКТА ДЛЯ КЭШИРОВАНИЯ HTTP-ОТВЕТА СЕРВЕРА102В итоге, Aspect.NET позволяет бесшовно расширять целевую логикуфункциональностью кэширования. Для этого необходимо создать аспектныйпроект в виде библиотеки классов, установить в него пакет Windows AzureCaching, после чего будет создан web.config файл с нужными секциями.