Привет всем ! Сегодня речь пойдет об отказоустойчивости облачных приложений. В принципе механизм, который будет рассматриваться в сегодняшней публикации, не новый. Мы все его прекрасно знаем – это обработка временных сбоев программы при помощи Retry Logic. Данная техника славится своей простотой и высокой надежностью.
В процессе написания облачного приложения, программист сталкивается с большим количеством программных сбоев, особое место среди которых занимают так называемые временные сбои. Это могут быть как проблемы с сетевой коммуникацией, так и проблемы связанные с определенными ограничениями используемого сервиса. Вероятность появления такого рода ошибок в облаке возрастает в разы, так как каждый сервис, предоставляемый платформой, содержит ряд ограничений. Например, в Azure Caching сервисе присутствует целый ряд ограничений, начиная от количества транзакций в час и заканчивая максимально допустимым количеством одновременных соединений (http://msdn.microsoft.com/en-us/library/windowsazure/hh697522.aspx#C_BKMK_FAQ8). Если ваше приложений превысит установленную квоту – сработает так называемый механизм тротлинга (throttling). При этом в приложении выскочит исключение, что естественно не порадует конечного пользователя. Как правило подобного рода сбои носят временный характер и если повторить операцию через определенный промежуток времени – она завершится успешно. Учитывая тот факт, что все облачные сервисы содержат ряд квот – данная проблема становится очень актуальной и важной.
Именно для решения подобного вида проблем командой Microsoft Patterns&Practices был разработан модуль библиотеки Enterprise Library, именуемый Thransient Fault Handling Application Block. Этот блок повышает отказоустойчивость вашего приложения путем предоставления механизмов для обработки временных сбоев. Блок доступен через NuGet, подключить его к вашему проекту можно при помощи следующей команды:
Блок оперирует таким понятием как стратегия. Стратегия позволяет блоку, во-первых, определить действительно ли сбой связан с временной проблемой, а во-вторых, предоставляет наилучший способ решения этой проблемы. На сегодняшний день вместе с блоком поставляются 4 стратегии для 4-х облачных сервисов:
Кроме того блок позволяет настроить собственную политику формирования временных интервалов, а также механизмы определения временных сбоев, что предоставляет нам прекрасные возможности по расширению этого полезного модуля Enterprise Library.
Познакомившись с предназначением блока и с принципами его функционирования, давайте посмотрим как программно можно его использовать для повышения отказоустойчивости приложений, использующих SQL Azure.
SQL Azure, как и многие другие, сервисы Windows Azure содержит ряд ограничений и квот, нарушение которых будет вести к "падениям" ваших приложений. Немного поискав в Интернете список ограничений SQL Azure я наткнулся на следующую табличку:
То есть, например, если наше приложение открыло “тяжелый” курсор на сервере и он стал “пожирать” процессорное время – мы получим в приложении ошибку с кодом 0х100 (на самом деле код ошибки будем немного другим, но нас сейчас это не сильно интересует), на которую необходимо как-то реагировать. Первый и самый простой вариант – это попробовать заново выполнить неудачную операцию. И сделаем мы это при помощи Transient Fault Handling Application Block. Блок содержит в себе механизмы, применимые как к чистому ADO.NET так и к Entity Framework. Вот пример, как изменить программный код с целью добавления логики повторного выполнения неудачной операции:
Как видим техника использования Transient Fault Handling Application Block довольно таки проста и понятна. Поэтому если в приложении вы используете вышеперечисленные Azure-сервисы (Storage, Service Bus, Caching, SQL Azure), не задумываясь прикручивайте retry-логику к нему – это сделает ваше приложение более отказоустойчивым, а ваши ночи более спокойными :)
Спасибо за внимание ! Надеюсь этот пост был для вас полезным.
Несколько ссылок для более глубокого знакомства с Transient Fault Handling Application Block:
В процессе написания облачного приложения, программист сталкивается с большим количеством программных сбоев, особое место среди которых занимают так называемые временные сбои. Это могут быть как проблемы с сетевой коммуникацией, так и проблемы связанные с определенными ограничениями используемого сервиса. Вероятность появления такого рода ошибок в облаке возрастает в разы, так как каждый сервис, предоставляемый платформой, содержит ряд ограничений. Например, в Azure Caching сервисе присутствует целый ряд ограничений, начиная от количества транзакций в час и заканчивая максимально допустимым количеством одновременных соединений (http://msdn.microsoft.com/en-us/library/windowsazure/hh697522.aspx#C_BKMK_FAQ8). Если ваше приложений превысит установленную квоту – сработает так называемый механизм тротлинга (throttling). При этом в приложении выскочит исключение, что естественно не порадует конечного пользователя. Как правило подобного рода сбои носят временный характер и если повторить операцию через определенный промежуток времени – она завершится успешно. Учитывая тот факт, что все облачные сервисы содержат ряд квот – данная проблема становится очень актуальной и важной.
Именно для решения подобного вида проблем командой Microsoft Patterns&Practices был разработан модуль библиотеки Enterprise Library, именуемый Thransient Fault Handling Application Block. Этот блок повышает отказоустойчивость вашего приложения путем предоставления механизмов для обработки временных сбоев. Блок доступен через NuGet, подключить его к вашему проекту можно при помощи следующей команды:
Install-Package EnterpriseLibrary.WindowsAzure.TransientFaultHandling
Блок оперирует таким понятием как стратегия. Стратегия позволяет блоку, во-первых, определить действительно ли сбой связан с временной проблемой, а во-вторых, предоставляет наилучший способ решения этой проблемы. На сегодняшний день вместе с блоком поставляются 4 стратегии для 4-х облачных сервисов:
- SQL Azure
- Windows Azure Service Bus
- Windows Azure Storage Service
- Windows Azure Caching Service
Кроме того блок позволяет настроить собственную политику формирования временных интервалов, а также механизмы определения временных сбоев, что предоставляет нам прекрасные возможности по расширению этого полезного модуля Enterprise Library.
Познакомившись с предназначением блока и с принципами его функционирования, давайте посмотрим как программно можно его использовать для повышения отказоустойчивости приложений, использующих SQL Azure.
SQL Azure, как и многие другие, сервисы Windows Azure содержит ряд ограничений и квот, нарушение которых будет вести к "падениям" ваших приложений. Немного поискав в Интернете список ограничений SQL Azure я наткнулся на следующую табличку:
Throttling type
|
Soft Throttling limit exceeded
|
Hard Throttling limit exceeded
|
Temporary disk space problem occurred
|
0x01
|
0x02
|
Temporary log space problem occurred
|
0x04
|
0x08
|
High-volume transaction/write/update activity exists
|
0x10
|
0x20
|
High-volume database input/output (I/O) activity exists
|
0x40
|
0x80
|
High-volume CPU activity exists
|
0x100
|
0x200
|
Database quota exceeded
|
0x400
|
0x800
|
Too many concurrent requests occurred
|
0x4000
|
0x8000
|
То есть, например, если наше приложение открыло “тяжелый” курсор на сервере и он стал “пожирать” процессорное время – мы получим в приложении ошибку с кодом 0х100 (на самом деле код ошибки будем немного другим, но нас сейчас это не сильно интересует), на которую необходимо как-то реагировать. Первый и самый простой вариант – это попробовать заново выполнить неудачную операцию. И сделаем мы это при помощи Transient Fault Handling Application Block. Блок содержит в себе механизмы, применимые как к чистому ADO.NET так и к Entity Framework. Вот пример, как изменить программный код с целью добавления логики повторного выполнения неудачной операции:
RetryPolicy retryPolicy = new RetryPolicy‹SqlAzureTransientErrorDetectionStrategy›(3, TimeSpan.FromSeconds(30)); using (ReliableSqlConnection connection = new ReliableSqlConnection(connectionString, retryPolicy, retryPolicy)) { try { connection.Open(); using (var command = connection.CreateCommand()) { command.CommandText = "SELECT * FROM Employees"; using (var rdr = cnn.ExecuteCommand‹IDataReader›(cmd)) { // } } } catch (Exception ex) { MessageBox.Show(ex.Message.ToString()); } }Как мы видим необходимо лишь задать политику и изменить стандартный класс SQLConnection на ReliableSqlConnection. В данном случае наша политика гласит: “Использовать стратегию определения временных падений SQL Azure. В случае неудачной операции – попробовать выполнить ее снова. Количество попыток равно 3. Интервал между попытками равен 30 секундам. В случае, если ничего не получится – передать исключение внешнему коду”. Похожим образом можно добавить логику повторных операций для приложений, использующих Entity Framework в качестве слоя для доступа к данным:
using (NorthwindEntities dc = new NorthwindEntities()) { RetryPolicy myPolicy = new RetryPolicy‹SqlAzureTransientErrorDetectionStrategy›(3); Employee e1 = myPolicy.ExecuteAction‹Employee›(() => (from x in dc.Employees where x.LastName == "King" select x).First()); }В данном случае мы снова создаем политику (логика работы такая же как и в предыдущем случае, так как 30-секундный интервал используется блоком по умолчанию). Но сам код немного изменился по сравнению с предыдущим случаем. Процесс создания контекста не изменился, изменился способ выполнения запроса. Он оборачивается методом политики ExecuteAction, принимающий в качестве параметра Action. Если запрос по каким-то причинам не выполнится, инфраструктура блока попробует запустить его заново по прошествии 30 секунд.
Как видим техника использования Transient Fault Handling Application Block довольно таки проста и понятна. Поэтому если в приложении вы используете вышеперечисленные Azure-сервисы (Storage, Service Bus, Caching, SQL Azure), не задумываясь прикручивайте retry-логику к нему – это сделает ваше приложение более отказоустойчивым, а ваши ночи более спокойными :)
Спасибо за внимание ! Надеюсь этот пост был для вас полезным.
Несколько ссылок для более глубокого знакомства с Transient Fault Handling Application Block:
Комментариев нет:
Отправить комментарий