(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Пакетная компиляция в ASP.NET (исходники)

Источник: GOTDOTNET
Дмитрий Мартынов

Наверное многие замечали, что первое обращение к ASPX странице занимает значительно больше времени, чем последующие и при этом заметно повышенное потребление ресурсов Веб-сервера. Это ASP.NET производит т.н. динамическую компиляцию или компиляцию "на-лету" (on-the-fly). Она происходит автоматически, когда браузер запрашивает страницу с сервера. Очевидно, что хотелось бы иметь средство избежать подобных задержек. Далее я рассмотрю, что же предлагает ASP.NET для борьбы с этим, а так же приведу некоторые детали того, как происходит обработка запросов к страницам с точки зрения динамической компиляции.

Немного теории

Как известно, ASP.NET в отличие от ASP производит компиляцию (а не интерпретацию) ASPX страниц. При такой компиляции для каждой страницы или группы страниц создается сборка (assembly) - динамическая библиотека dll.

Замечу, что речь идет именно о страницах ASPX и серверных скриптах внутри этих страниц, а не о т.н. code behind файлах, которые должны быть заранее скомпилированы и размещены в папке BIN или глобальном кеше сборок (GAC - Global Assembly Cache). Использование code behind файлов является предпочтительным способом, так как позволяет добиться разделения кода и представления. К сожалению это не исключает компиляции ASPX страниц.

Сборка содержит MSIL (MicroSoft Intermediate Language) код, который в свою очередь перед фактическим исполнением компилируется в исполняемый код. Единица компиляции - вызываемый метод. Это т.н. JIT-компиляция. Соственно говоря, этим уже занимается не ASP.NET, а.NET Framework, так как с точки зрения Framework скомпилированная ASPX страница - это обычная сборка, содержащая несколько классов, поддерживающих определенные интерфейсы.

После JIT-компиляции исполняемый код метода кешируется и последующие обращения к этому методу происходят напрямую.

Таким образом имеются две области, в которых происходят задержки при обращении к ASPX странице:

  • компиляция "на-лету"
  • JIT-компиляция

Последнюю мы рассматривать не будем, а вот в процесс компиляции "на-лету" можно вмешаться.

Первый запрос страницы

ASP.NET определяет, что требуется компиляция страницы, в случае, если для нее нет сохраненной сборки или страница была изменена. Далее производятся две основные операции:

  • разбор (parsing) страницы и генерация исходного кода. Данный код можно увидеть при включенной отладке (см. ниже "Как устроена страница").
  • компилиция кода страницы и сохранение полученной сборки

Если страница уже была ранее скомпилирована, т.е. для нее есть соответствующая сборка, то данная сборка используется в качестве обработчика запрошенной страницы.

Давайте представим себе реальную ситуацию, когда Веб-сайт содержит несколько сотен или тысяч страниц. Что происходит, когда пользователь запрашивает страницу с сервера? Правильно - компиляция этой страницы. Теперь представьте, что сайт нагружен. Очевидно, что в этом случае время отклика сервера возрастает, а это не есть хорошо. Кстати - это касается и Веб-сервисов, но это немного другая история, так как здесь вмешиваются механизмы Reflection и сериализации.

Что же можно сделать, чтобы оптимизировать процесс динамической компиляции?

ASP.NET предлагает средство, называемое "пакетная компиляция" (batch compilation).

Пакетная компиляция

За процесс компиляции отвечает элемент конфигурации <compilation> файла web.config:


<configuration>
<system.web>
<compilation>
<compilation debug="true/false"
batch="true/false"
batchTimeout="число секунд"
defaultLanguage="язык"
maxBatchSize="максимальное число страниц на пакетную компиляцию"
maxBatchGeneratedFileSize="максимальный размер
сгенерированного исходного файла в KB"
tempDirectory="директория для временных файлов при компиляции">
</compilation>

Атрибут  Значение  Описание 
Debug    Компиляция с отладочной информацией. По умолчанию false 
  true  Компиляция с отладочной информацией. Сохраняются исходные файлы на языке, указанном в атрибуте defaultLanguage.
Замечание: при включенной отладочной информации пакетная компиляция не производится 
  false  Компиляция без отладочной информации.
defaultLanguage    Язык, в который разбирается страница. По умолчанию vb, но Visual Studio.NET устанавливает его в c#
batch    Пакетная компиляция
  true  Пакетная компиляция включена
  false  Пакетная компиляция выключена
batchTimeout    Указывает тайм-аут, в секундах, для пакетной компиляции. Если компиляция не может быть выполнена за этот период, то компилятор возвращается к стандартному режиму компиляции для текущей страницы
maxBatchGeneratedFileSize    Максимальный размер сгенерированного исходного файла в KB
maxBatchFileSize    Максимальное кол-во страниц на одну пакетную компиляцию
tempDirectory    Директория для временных файлов при компиляции

Чтобы включить эту опцию, надо установить атрибут batch равным true, а debug равным false.

Что же произойдет в этом случае ? При запросе любой страницы из каталога, ASP.NET скомпилирует все страницы и создаст одну сборку. Т.е. вместо множества небольших dll (одна dll для одной страницы) получится одна большая dll для всех страниц в этом каталоге.

Здесь надо заметить, что пакетная компиляция производится на основе каталога, а не для всего Веб-приложения.

Очевидно преимущество такого подхода - не надо компилировать и разбирать страницу за страницей при первом к ним обращении. Но как говорится, бесплатный сыр бывает только в мышеловках. И данный подход - не исключение. Отрицательная сторона заключается в том, что такая компиляция занимает больше ресурсов сервера и может увеличить время отклика страниц, участвующих в такой компиляции. Но на это есть свое противоядие - "пред-пакетная" компиляция (pre-batch compilation). Т.е. перед тем, как кто-либо запросит любую страницу с сервера, Вы сами обращаетесь к любой странице, тем самым инициируя процесс пакетной компиляции и заставляя ASP.NET создать и закешировать все страницы сайта. Отсюда мораль - всегда перед передачей Веб-приложения в "производство" запрашивайте страницы из всех виртуальных каталогов.

Технические детали

Теперь немного о технических деталях. Любая страница ASPX при обращении к ней автоматически компилируется и попадает в:

%systemroot%/Microsoft.NET/Framework/<версия>/Temporary ASP.NET Files/<сайт>/nnnnn/mmmm

(nnnnn и mmmm - случайные последовательности).

Часть пути "%systemroot%/Microsoft.NET/Framework/<версия>/Temporary ASP.NET Files" может быть изменена с помощью атрибута tempDirectory

На моем компьютере - это:

C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\Temporary ASP.NET Files\TestProject\b5afd0e9\e951ffc7

В зависимости от значения атрибута batch, там будет находиться один или более файлов вида aabbcc.dll, а так же настройки для связывания (Test.aspx.mmmmm.xml).

Хитрость заключается в том, что в случае с batch=true, там будет всего одна dll, но в настройках связывания (напоминаю - это файлы вида Test.aspx.mmmmm.xml) будет указана одна и та же dll для всех страниц. Название dll выбирается случайным образом, аналогично выбору имени временного файла.

Также эта директория (а точнее поддиректория assembly) используется для т.н. "теневого" копирования используемых в Веб-приложении dll, что позволяет ASP.NET не блокировать их (вспомните ASP и COM).

Что происходит, если меняется одна страница

А теперь - самое интересное. Вы включили batch=true, произвели предкомпиляцию и наслаждаетесь быстрой работой сайта. В этот момент оказывается, что необходимо исправить одну страницу, скажем Test.aspx. Что происходит при следующем запросе этой страницы ?

ASP.NET компилирует ее и создает отдельную сборку со случайным именем, например xxyyzz.dll. Потом меняется настройка связывания, так что теперь ASP.NET знает: "код выполнения страницы Test.aspx находится не в aabbcc.dll, а в xxyyzz.dll". При этом в старой сборке остается код для страницы Test.aspx, но он не используется.

Как устроена страница или магия в действии

Если заглянуть в xxyyzz.dll с помощью утилиты ildasm (входит в состав .NET Framework SDK; также устанавливается с Visual Studio.NET), то можно убедиться, что в ней находится класс Test_aspx, который наследован от того класса, который вы использовали в качестве code behind (Test.aspx.cs, если таковой имелся, что не является обязательным; это класс, про который директива @Page в начале Вашей странице сообщает: Codebehind="Test.aspx.cs" Inherits="TestProject.Test"), который в свою очередь наследован от System.Web.UI.Page - базовый обработчик ASPX страниц (т.е. класс, поддерживающий интерфейс IHttpHandler и участвующий в конвеере запросов IIS/ASP.NET).

Для лучшего понимания процесса надо установить debug=true.

Замечу, что при этом перестанет работать пакетная компиляция, но это дает нам возможность увидеть, как наша страница выглядит в C#.

Тем, кто не собирается заниматься подобными изысканиями могу сообщить, что в основном там следующее:

  • создание зависимости на исходный файл (Test.aspx), служащей для определения факта его изменения
  • создание всех серверных элементов управления и инициализация базового класса (напомню, базовый класс - это Ваш code behind Test.aspx.cs). Собственно здесь и появляется та магическая связь между идентификаторами серверных элементов управления и Вашим кодом (а точнее полями Вашего класса)
  • построение т.н. "дерева" элементов управления

Если запустить Task Manager, то можно заметить, как процесс csc.exe появляется и исчезает. Это запускается компилятор C#, который собственно и производит компиляцию исходного файла, полученного в результате разбора страницы.

После чего данная сборка используется конвеером ASP.NET для обработки запроса на ресурс Test.aspx.

Заключение

Несмотря на то, что при программировании ASP.NET не требуется знание работы среды исполнения, но в реальных проектах часто требуется тонкая настройка Веб-сервера, особенно под нагрузкой. Надеюсь, что информация в данной статье поможет разработчикам лучше понять работу ASP.NET и, возможно, решить некоторые проблемы, в частности, с ошибками по правам доступа, кешированием компонентов и т.п.

Ссылки по теме


 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 02.06.2007 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
Microsoft Office для дома и учебы 2019 (лицензия ESD)
Microsoft Office 365 Профессиональный Плюс. Подписка на 1 рабочее место на 1 год
Microsoft Office 365 Персональный 32-bit/x64. 1 ПК/MAC + 1 Планшет + 1 Телефон. Все языки. Подписка на 1 год.
Microsoft Office 365 для Дома 32-bit/x64. 5 ПК/Mac + 5 Планшетов + 5 Телефонов. Подписка на 1 год.
Microsoft 365 Business Standard (corporate)
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Безопасность компьютерных сетей и защита информации
Новости ITShop.ru - ПО, книги, документация, курсы обучения
CASE-технологии
Программирование на Microsoft Access
OS Linux для начинающих. Новости + статьи + обзоры + ссылки
Corel DRAW - от идеи до реализации
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100