Рекомендации по веб-разработке (создание Real-World облачных приложений с помощью Azure)
Рик Андерсон(Rick Anderson),Том Дайкстра (Tom Dykstra)
Скачать проект fix it или скачать электронную книгу
Электронная книга Building Real World Cloud Apps with Azure (Создание реальных облачных приложений с помощью Azure ) основана на презентации, разработанной Скоттом Гатри. В ней описано 13 шаблонов и методик, которые помогут вам успешно разрабатывать веб-приложения для облака. Сведения об электронной книге см. в первой главе.
Первые три шаблона касались настройки гибкого процесса разработки; остальные касаются архитектуры и кода. Это коллекция рекомендаций по веб-разработке:
- Веб-серверы без отслеживания состояния за интеллектуальной подсистемой балансировки нагрузки.
- Избегайте состояния сеанса (или, если вы не можете избежать этого, используйте распределенный кэш, а не базу данных).
- Используйте CDN для пограничного кэширования статических файловых ресурсов (изображений, скриптов).
- Используйте асинхронную поддержку .NET 4.5 , чтобы избежать блокировки вызовов.
Эти методики действительны для любой веб-разработки, а не только для облачных приложений, но они особенно важны для облачных приложений. Они работают вместе, чтобы помочь вам оптимально использовать гибкое масштабирование, предлагаемое облачной средой. Если вы не будете следовать этим методикам, при попытке масштабирования приложения возникнут ограничения.
Веб-уровень без отслеживания состояния за интеллектуальной подсистемой балансировки нагрузки
Веб-уровень без отслеживания состояния означает, что данные приложения не хранятся в памяти веб-сервера или файловой системе. Сохранение веб-уровня без отслеживания состояния позволяет улучшить взаимодействие с клиентами и сэкономить деньги:
- Если веб-уровень не содержит состояния и находится за подсистемой балансировки нагрузки, вы можете быстро реагировать на изменения в трафике приложений, динамически добавляя или удаляя серверы. В облачной среде, где вы платите только за серверные ресурсы до тех пор, пока вы действительно используете их, возможность реагировать на изменения спроса может привести к значительной экономии.
- Веб-уровень без отслеживания состояния в архитектуре гораздо проще масштабировать приложение. Это также позволяет быстрее реагировать на потребности масштабирования и тратить меньше средств на разработку и тестирование в процессе.
- Облачные серверы, например локальные серверы, необходимо периодически устанавливать исправления и перезагружать; и если веб-уровень не содержит состояния, перенаправка трафика при временном отключении сервера не приведет к ошибкам или непредвиденному поведению.
Большинство реальных приложений должны хранить состояние для веб-сеанса; main здесь не хранить его на веб-сервере. Состояние можно хранить другими способами, например на клиенте в файлах cookie или вне процесса на стороне сервера в ASP.NET состоянии сеанса с помощью поставщика кэша. Файлы можно хранить в хранилище BLOB-объектов Windows Azure , а не в локальной файловой системе.
Пример того, как легко масштабировать приложение на веб-сайтах Windows Azure, если веб-уровень не имеет состояния, см. на вкладке Масштабирование веб-сайта Windows Azure на портале управления:
Если вы хотите добавить веб-серверы, просто перетащите ползунок счетчика экземпляров вправо. Задайте для него значение 5 и нажмите кнопку Сохранить. В течение нескольких секунд у вас будет 5 веб-серверов в Windows Azure, обрабатывая трафик веб-сайта.
Так же легко задать для счетчика экземпляров значение 3 или обратное значение 1. При уменьшении масштаба вы сразу же начинаете экономить деньги, так как Плата за Windows Azure взимается по минутам, а не по часам.
Вы также можете указать, что Windows Azure автоматически увеличивает или уменьшает количество веб-серверов в зависимости от использования ЦП. В следующем примере, когда загрузка ЦП ниже 60 %, количество веб-серверов уменьшится до минимума 2, а если загрузка ЦП превышает 80 %, количество веб-серверов будет увеличено до максимум 4.
Или что делать, если вы знаете, что ваш сайт будет занят только в рабочее время? Вы можете указать, что Windows Azure будет запускать несколько серверов в дневное время и уменьшать их до одного сервера по вечерам, ночам и выходным. На следующих снимках экрана показано, как настроить веб-сайт для запуска одного сервера в нерабочее время и 4 серверов в рабочее время с 8:00 до 17:00.
И, конечно, все это можно сделать как в скриптах, так и на портале.
Возможности приложения по горизонтальному масштабированию в Windows Azure практически неограничен, при условии, что вы избегаете препятствий для динамического добавления или удаления серверных виртуальных машин, сохраняя веб-уровень без отслеживания состояния.
Отказ от использования состояния сеанса
Не хранить определенные виды состояний сеансов пользователя в реальном облачном приложении бывает нецелесообразно, но разные подходы по-разному влияют на производительность и масштабируемость. Если вам нужно хранить состояния, лучшим решением будет хранить небольшой объем состояний в файлах cookie. Если это невозможно, следующим оптимальным решением является использование ASP.NET состояния сеанса с поставщиком для распределенного кэша в памяти. Худшее решение с точки зрения масштабируемости и производительности — использовать базу данных резервного поставщика состояний сеансов.
Использование CDN для кэширования ресурсов статических файлов
CDN — это аббревиатура сети доставки содержимого. Вы предоставляете поставщику CDN статические файлы файлов, такие как изображения и файлы скриптов, и поставщик кэширует эти файлы в центрах обработки данных по всему миру, чтобы пользователи, получающие доступ к приложению, относительно быстрый ответ и низкую задержку для кэшированных ресурсов. Это ускоряет общее время загрузки сайта и уменьшает нагрузку на веб-серверы. Сети CDN особенно важны, если вы достигаете аудитории, которая широко распространена географически.
В Windows Azure есть СЕТЬ CDN, и вы можете использовать другие сети CDN в приложении, которое выполняется в Windows Azure или любой среде веб-размещения.
Используйте асинхронную поддержку .NET 4.5, чтобы избежать блокировки вызовов
В .NET 4.5 улучшены языки программирования C# и VB, чтобы упростить асинхронную обработку задач. Преимущество асинхронного программирования заключается не только в ситуациях параллельной обработки, например при одновременном запуске нескольких вызовов веб-служб. Это также позволяет веб-серверу работать более эффективно и надежно в условиях высокой нагрузки. Веб-сервер имеет только ограниченное количество доступных потоков, и в условиях высокой нагрузки, когда используются все потоки, входящие запросы должны ждать, пока потоки будут освобождены. Если код приложения не обрабатывает такие задачи, как запросы к базе данных и вызовы веб-служб, асинхронно, многие потоки неоправданно связаны, пока сервер ожидает ответа ввода-вывода. Это ограничивает объем трафика, который сервер может обрабатывать в условиях высокой нагрузки. При асинхронном программировании потоки, ожидающие возврата данных веб-службой или базой данных, освобождаются для обслуживания новых запросов до получения данных . На занятом веб-сервере сотни или тысячи запросов могут быть обработаны быстро, что в противном случае ожидало бы освобождения потоков.
Как вы видели ранее, уменьшить количество веб-серверов, обрабатываемых веб-сайтом, так же просто, как и увеличить их. Таким образом, если сервер может достичь большей пропускной способности, вам не нужно так много, и вы можете снизить затраты, так как для заданного объема трафика требуется меньше серверов, чем в противном случае.
Поддержка асинхронной модели программирования .NET 4.5 включена в ASP.NET 4.5 для веб-формы, MVC и веб-API; в Entity Framework 6 и в API службы хранилища Windows Azure.
Поддержка асинхронной синхронизации в ASP.NET 4.5
В ASP.NET 4.5 поддержка асинхронного программирования была добавлена не только в язык, но и в платформы MVC, веб-формы и веб-API. Например, метод действия контроллера ASP.NET MVC получает данные из веб-запроса и передает их в представление, которое затем создает HTML-код для отправки в браузер. Часто методу действия требуется получить данные из базы данных или веб-службы, чтобы отобразить их на веб-странице или сохранить данные, введенные на веб-странице. В этих сценариях легко сделать метод действия асинхронным: вместо возврата объекта ActionResult вы возвращаете Task<ActionResult> и помечаете метод асинхронным ключевое слово. В методе, когда строка кода запускает операцию, которая включает время ожидания, вы помечаете ее ключевое слово await.
Ниже приведен простой метод действия, который вызывает метод репозитория для запроса к базе данных:
public ActionResult Index()
{
string currentUser = User.Identity.Name;
var result = fixItRepository.FindOpenTasksByOwner(currentUser);
return View(result);
}
А вот тот же метод, который обрабатывает вызов базы данных асинхронно:
public async Task<ActionResult> Index()
{
string currentUser = User.Identity.Name;
var result = await fixItRepository.FindOpenTasksByOwnerAsync(currentUser);
return View(result);
}
Под обложкой компилятор создает соответствующий асинхронный код. Когда приложение выполняет вызов FindTaskByIdAsync
, ASP.NET выполняет FindTask
запрос, а затем отматывает рабочий поток и делает его доступным для обработки другого запроса. FindTask
После выполнения запроса поток перезапускается, чтобы продолжить обработку кода, который поступает после этого вызова. В промежуток между FindTask
началом запроса и возвратом данных у вас есть поток, доступный для выполнения полезной работы, которая в противном случае была бы связана с ожиданием ответа.
Существуют некоторые издержки для асинхронного кода, но в условиях низкой нагрузки они незначительны, в то время как в условиях высокой нагрузки вы можете обрабатывать запросы, которые в противном случае были бы удержаны в ожидании доступных потоков.
Такой тип асинхронного программирования можно было выполнять с ASP.NET 1.1, но это было трудно писать, подвержено ошибкам и трудно выполнять отладку. Теперь, когда мы упростили кодирование в ASP.NET 4.5, нет причин больше не делать этого.
Поддержка асинхронной синхронизации в Entity Framework 6
В рамках асинхронной поддержки в версии 4.5 мы добавили асинхронную поддержку вызовов веб-служб, сокетов и операций ввода-вывода файловой системы, но наиболее распространенным шаблоном для веб-приложений является попадание в базу данных, а библиотеки данных не поддерживают асинхронную поддержку. Теперь в Entity Framework 6 добавлена асинхронная поддержка доступа к базе данных.
В Entity Framework 6 все методы, вызывающие отправку запроса или команды в базу данных, имеют асинхронные версии. В этом примере показана асинхронная версия метода Find .
public async Task<FixItTask> FindTaskByIdAsync(int id)
{
FixItTask fixItTask = null;
Stopwatch timespan = Stopwatch.StartNew();
try
{
fixItTask = await db.FixItTasks.FindAsync(id);
timespan.Stop();
log.TraceApi("SQL Database", "FixItTaskRepository.FindTaskByIdAsync", timespan.Elapsed, "id={0}", id);
}
catch(Exception e)
{
log.Error(e, "Error in FixItTaskRepository.FindTaskByIdAsynx(id={0})", id);
}
return fixItTask;
}
Эта асинхронная поддержка работает не только для вставок, удаления, обновлений и простых операций поиска, но и для запросов LINQ:
public async Task<List<FixItTask>> FindOpenTasksByOwnerAsync(string userName)
{
Stopwatch timespan = Stopwatch.StartNew();
try
{
var result = await db.FixItTasks
.Where(t => t.Owner == userName)
.Where(t=>t.IsDone == false)
.OrderByDescending(t => t.FixItTaskId).ToListAsync();
timespan.Stop();
log.TraceApi("SQL Database", "FixItTaskRepository.FindTasksByOwnerAsync", timespan.Elapsed, "username={0}", userName);
return result;
}
catch (Exception e)
{
log.Error(e, "Error in FixItTaskRepository.FindTasksByOwnerAsync(userName={0})", userName);
return null;
}
}
Async
Существует версия метода , ToList
так как в этом коде это метод, который вызывает отправку запроса в базу данных. Методы Where
и настраивают только запрос, в ToListAsync
то время как метод выполняет запрос и сохраняет ответ в переменной result
OrderByDescending
.
Сводка
Вы можете реализовать рекомендации по веб-разработке, описанные здесь, в любой платформе веб-программирования и в любой облачной среде, но у нас есть средства в ASP.NET и Windows Azure, чтобы упростить эту задачу. Если вы будете следовать этим шаблонам, вы сможете легко масштабировать веб-уровень и свести к минимуму расходы, так как каждый сервер сможет обрабатывать больше трафика.
В следующей главе рассматривается, как облако реализует сценарии единого входа.
Ресурсы
Дополнительные сведения см. в следующих ресурсах.
Веб-серверы без отслеживания состояния:
- Шаблоны и методики Майкрософт. Руководство по автомасштабированию.
- Отключение сопоставления экземпляров ARR на веб-сайтах Windows Azure. В записи блога Эреза Бенари объясняется сходство сеансов на веб-сайтах Windows Azure.
CDN:
- FailSafe: создание масштабируемых, устойчивых Облачные службы. Серия видео из девяти частей Ульрих Хоманн, Марк Меркури и Марк Симмс. См. обсуждение CDN в эпизоде 3, начиная с 1:34:00.
- Шаблон размещения статического содержимого в шаблонах и методиках Майкрософт
- Отзывы CDN. Общие сведения о множестве CDN.
Асинхронное программирование:
- Использование асинхронных методов в ASP.NET MVC 4. Учебник Рика Андерсона.
- Асинхронное программирование с помощью Async и Await (C# и Visual Basic). Технический документ MSDN, в которому объясняется обоснование асинхронного программирования, принцип его работы в ASP.NET 4.5 и написание кода для его реализации.
- Асинхронный запрос и сохранение Entity Framework
- FailSafe: создание масштабируемых, устойчивых Облачные службы. Серия видео из девяти частей Ульрих Хоманн, Марк Меркури и Марк Симмс. Обсуждение влияния асинхронного программирования на масштабируемость см. в эпизодах 4 и 8.
- Магия использования асинхронных методов в ASP.NET 4.5 плюс важные моменты. Запись в блоге Скотта Хансельмана( Scott Hanselman), в основном об использовании асинхронных приложений в ASP.NET Web Forms приложениях.
Дополнительные рекомендации по веб-разработке см. в следующих ресурсах:
- Пример приложения Fix It — рекомендации. В приложении к этой электронной книге приводится ряд рекомендаций, которые были реализованы в приложении Fix It.
- Контрольный список веб-разработчиков