[Перевод] Различия между компиляцией веб-сайта и веб-приложения
Существует множество разновидностей модулей ASP.NET на основе различных платформ, таких как Web Forms, Web Pages, Model-View-Controller (MVC) и самой новой — Core. В этой статье я хочу рассмотреть ряд различий между компиляцией веб-сайта ASP.NET и веб-приложения ASP.NET.
Компиляция веб-сайта (рис. 1) и веб-приложения (рис. 2).
Рис. 1: веб-сайт ASP.NET и различие между веб-сайтом ASP.NET и веб-приложением ASP.NET
Рис. 2: веб-приложение ASP.NET и различие между веб-сайтом ASP.NET и веб-приложением ASP.NET
В этой статье речь пойдет не о внутреннем устройстве проектов ASP.NET, а об опыте, который я приобрел во время работы на платформе Azure App Service. Внутреннее устройство уже задокументировано здесь — «Precompiling Your Website (C#)» («Предварительная компиляция веб-сайта на языке C#»). Вы должны понять разницу между автоматической и явной компиляцией. Кроме того, если вы имеете дело с веб-сайтом ASP.NET, серьезно подумайте о предварительной компиляции с помощью aspnet_compiler.exe, как описано в статье «How to: Precompile ASP.NET Web Sites» («Как выполнить предварительную компиляцию веб-сайтов ASP.NET»).
Вот еще ряд публикаций, которые помогут вам расширить кругозор по этому вопросу и изучить другие темы:
Итак, с чего все началось? Я захотел проверить, правильно ли я понимаю процесс компиляции модулей ASP.NET в сборки, и решил сделать это в среде Azure App Service. Я уже имел понятие о временных файлах ASP.NET, о компиляции файлов ASPX в сборку .dll и о месте их хранения на автономном сервере. Я был уверен, что на платформе App Service первые два пункта реализованы аналогичным образом, но сомневался в третьем —, а именно в том, где хранятся скомпилированные сборки. Вот я и написал код, позволяющий это узнать.
public partial class _default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
LabelFileLocation.Text = $"{System.Web.HttpRuntime.CodegenDir}";
rptResults1.DataSource = System.IO.Directory.GetFiles(System.Web.HttpRuntime.CodegenDir, "*.dll");
rptResults1.DataBind();
}
}
Я представил результаты следующим образом (обобщенно)
<%# Container.DataItem %>
Затем я опубликовал этот код на платформе App Service.
При первом обращении к веб-сайту я получил результат, показанный на рис. 3 (изначально в корне моего веб-сайта ASP.NET было три страницы)
Рис. 3: компиляция веб-сайта ASP.NET на платформе Azure App Service
Я перезапустил веб-сайт, и двоичные файлы скомпилировались в новую сборку (рис. 4). Это было довольно неожиданно, поскольку я выполнил только перезагрузку и не делал никаких развертываний или изменений.
Рис. 4: компиляция веб-сайта ASP.NET на платформе Azure App Service
Я поискал в KUDU каталог сборки и не нашел его; это было очень странно.
После щелчка по ссылкам «Another Page» и «And another Page» все мои страницы были скомпилированы в одну сборку, и я весьма удивился, обнаружив это, поскольку в моем файле web.config было установлено значение debug=true.
Мне нужно было выяснить ответы на следующие вопросы:
- Почему мое приложение перекомпилировалось после перезагрузки, хотя я не выполнял никаких развертываний или изменений конфигурации?
- Почему я не нашел сборку в KUDU, хотя мой исходный код был правильным?
- Почему мое приложение скомпилировалось в единую сборку, хотя в файле web.config был установлен параметр debug=true?
Ответ на первый вопрос состоял в том, что на самом деле я смотрел на сборку KUDU, а не на ту, которая была скомпилирована для App Service. Взгляните на рисунок 2 в статье «Create a memory dump for your slow performing Web App» («Создайте дамп памяти для вашего медленного веб-приложения»). Здесь показано, что KUDU работает в другом процессе, чем App Service. Поэтому KUDU перекомпилировал себя при создании экземпляра, и это не был мой экземпляр App Service.
Со вторым вопросом я также разобрался на основе сведений, полученных по первому вопросу. Опущу подробности о конфигурации файлов на платформе App Service и скажу, что мне удалось отобразить на этой платформе мои сборки веб-сайтов ASP.NET: для этого я установил значение WEBSITE_DISABLE_SCM_SEPARATION равным true (см. рис. 5). Делайте это только для тестирования и (или) отладки и ни для чего больше. Я не рекомендую сопоставлять несколько страниц веб-сайта одному процессу в App Service. Завершив отладку, сбросьте это значение и вновь разделите процессы.
Рис. 5: компиляция веб-сайта ASP.NET в Azure App Service; не могу найти временные файлы ASP.NET на KUDU
Ответ на третий вопрос заключался в том, что при наличии файла Web.Debug.config в процессе развертывания атрибут debug=true удаляется.
Я писал о XDT-файлах здесь, здесь и здесь, но в данном случае пришлось немного подумать, чтобы понять (вспомнить, осознать) их значение.
После установки параметра WEBSITE_DISABLE_SCM_SEPARATION равным true, я сделал остановку и запуск, иными словами, холодный запуск… и увидел, что на самом деле и SCM/KUDU, и мой веб-сайт запустились в одном процессе (рис. 6.)
Рис. 6: компиляция веб-сайта ASP.NET в Azure App Service; не могу найти временные файлы ASP.NET на KUDU
Инициируется публикация и компиляция default.aspx, имя сборки остается неизменным после всех запросов (рис. 7).
Рис. 7: компиляция веб-сайта ASP.NET на платформе Azure App Service
Чтобы убедиться в этом, я снял дамп памяти процесса, снял дамп модуля и проанализировал его. Честно говоря, я по-прежнему был озадачен результатом, выведенным полученной сборкой, поскольку разобрался с параметром debug=true только после завершения всех тестов. Иногда я пишу статьи не в том порядке, в котором следуют события. В замешательстве я решил протестировать пакетную компиляцию; читайте об этом здесь: «Сompilation Element (ASP.NET Settings Schema)» («Элемент сompilation — схема веб-параметров в ASP.NET»). Я ожидал, что будет скомпилировано по одной сборке на каждую страницу, поэтому результат (см. рис. 8) стал полной неожиданностью.
Рис. 8: компиляция веб-сайта ASP.NET на платформе Azure App Service
Я ожидал увидеть по одной сборке на каждую страницу, поскольку считал, что работаю с параметром debug=true. Читая о пакетной компиляции, я понял, что она компилирует все страницы в сборку, содержащуюся в определенном каталоге. Поэтому я создал два каталога и поместил файлы ASPX в каждый из них. PID не изменялся, поэтому не было «холодного старта» (рис. 9).
Рис. 9: компиляция веб-сайта ASP.NET на платформе Azure App Service
Однако сайт действительно перекомпилировался в другой двоичный файл, но остался в том же каталоге (пути) (рис. 10).
Рис. 10: компиляция веб-сайта ASP.NET на платформе Azure App Service
Я сделал дамп памяти, чтобы полностью убедиться в правильности своих выводов. И, как только я обратился к корню сайта и увидел, что все страницы в каталоге скомпилированы, то понял, что моя гипотеза о пакетной компиляции подтвердилась (рис. 11).
Рис. 11: компиляция веб-сайта ASP.NET на платформе Azure App Service
Я перешел по ссылке «Directory 1» и увидел еще одну сборку (рис. 12).
Рис. 12: компиляция веб-сайта ASP.NET на платформе Azure App Service
Я снова сделал дамп памяти, снял дамп модуля и увидел, что он действительно соответствует странице «Directory 1» (рис 13).
Рис. 13: компиляция веб-сайта ASP.NET на платформе Azure App Service
Я проделал то же самое для страницы «Directory 2» (рис. 14 и 15).
Рис. 14: компиляция веб-сайта ASP.NET на платформе Azure App Service
Рис. 15: компиляция веб-сайта ASP.NET на платформе Azure App Service
Я также получил возможность перейти к самим сборкам в SCM/KUDU (рис. 16).
Рис. 16: компиляция веб-сайта ASP.NET на платформе Azure App Service
Как только я выяснил проблему с параметром debug=true, все встало на свои места, и это был хороший опыт обучения. Надеюсь, что моя статья окажется полезной для вас.
Полезные ресурсы
Руководство по архитектуре облачных приложений
Используйте структурированный подход к разработке облачных приложений. В этой 300-страничной электронной книге об архитектуре облачных вычислений рассматриваются рекомендации по архитектуре, разработке и внедрению, которые применяются независимо от выбранной облачной платформы. В это руководство включены шаги по:
- выбору правильного стиля архитектуры облачного приложения для своего приложения или решения;
- выбору соответствующих технологий вычислений и хранения данных;
- внедрению 10 принципов разработки для создания масштабируемого, отказоустойчивого и управляемого приложения;
- следованию пяти принципам создания качественного программного обеспечения, гарантирующего успех вашего облачного приложения;
- использованию конструктивных шаблонов, предназначенных для проблемы, которую вы пытаетесь решить.
→ Скачать
Руководство разработчика по Azure
Из этого обновления руководства разработчика по Azure вы узнаете, насколько полный набор служб для программной платформы Azure соответствует вашим задачам. Здесь вы найдете сведения об архитектурных подходах и наиболее распространенных ситуациях, которые возникают при создании облачных приложений.
→ Скачать
Основы Microsoft Azure
Эта книга дает представление о важной информации о ключевых службах Azure для разработчиков и ИТ-специалистов, которые не знакомы с облачными вычислениями. Пошаговые демонстрации включены, чтобы помочь читателю понять, как начать работу с каждой из ключевых служб. Каждая глава является самостоятельной, не требуется выполнять практические демонстрации из предыдущих глав, чтобы понять какую-либо конкретную главу.
В этой книге рассматриваются следующие темы:
- Начало работы с Azure;
- Служба приложений Azure и веб-приложения;
- Виртуальные машины;
- Служба хранилища;
- Базы данных;
- Дополнительные службы Azure.
→ Скачать
Полезные ссылки