Автор: Роб Ховард Перевод: Тропическая рыба
В этой статье обсуждаются:
· Общие секреты производительности ASP.NET
· Полезные советы и рекомендации по повышению производительности ASP.NET
· Рекомендации по использованию баз данных в ASP.NET
· Кэширование и фоновая обработка в ASP.NET.
Написать веб-приложение с использованием ASP.NET невероятно просто. Это настолько просто, что многие разработчики не тратят время на создание хорошо работающих своих приложений. В этой статье я рекомендую 10 советов по написанию высокопроизводительных веб-приложений. Я не буду ограничивать свое обсуждение приложениями ASP.NET, поскольку приложения ASP.NET — это лишь подмножество веб-приложений. Эта статья не претендует на то, чтобы стать исчерпывающим руководством по оптимизации производительности веб-приложений — для этого легко можно написать целую книгу. Вместо этого мы должны рассматривать эту статью как хорошую отправную точку.
До того, как я стал трудоголиком, я много занимался скалолазанием. Прежде чем совершить какое-либо восхождение, я предпочитаю просмотреть маршруты в путеводителе и прочитать рекомендации людей, побывавших на вершине. Но независимо от того, насколько хорошо написан путеводитель, вам нужен реальный опыт скалолазания, прежде чем пытаться достичь сложной цели. Точно так же вы можете научиться писать высокопроизводительные веб-приложения только тогда, когда вам придется решать проблемы с производительностью или запускать сайт с высокой пропускной способностью.
Мой личный опыт получен в результате работы в качестве менеджера базовой программы в команде ASP.NET в Microsoft, поддержки и управления сайтом www.asp.net , а также помощи в проектировании сервера сообщества, одного из нескольких известных приложений ASP.NET (форумы ASP.NET). , .Text и nGallery подключены к одной платформе). Я уверен, что некоторые из этих советов, которые помогли мне, пригодятся и вам.
Вам следует рассмотреть возможность разделения вашего приложения на несколько логических уровней. Возможно, вы слышали о трехуровневой (или n-уровневой) архитектуре. Обычно это предписанные структурные шаблоны, которые физически делят бизнес и/или оборудование на функциональные подразделения. Если система требует большего масштаба, можно легко добавить больше оборудования. Однако это приведет к снижению производительности, связанному с скачками в бизнесе и машинах, поэтому нам следует избегать этого. Поэтому, когда это возможно, старайтесь запускать страницу ASP.NET и связанные с ней компоненты в одном приложении.
Из-за разделения кода и границ между уровнями использование веб-служб или удаленного взаимодействия может снизить производительность на 20 % и более.
Уровень данных немного отличается, потому что обычно лучше иметь оборудование, выделенное для базы данных. Однако стоимость перехода процесса к базе данных по-прежнему высока, поэтому производительность на уровне данных должна быть вашим первым соображением при оптимизации кода.
Прежде чем вкладывать средства в устранение проблем с производительностью вашего приложения, обязательно проанализируйте свое приложение, чтобы обнаружить основную причину проблемы. Ключевые счетчики производительности (например, тот, который показывает процент времени, затраченного на сборку мусора) также очень полезны для определения того, где приложение проводит большую часть своего времени. Хотя те места, где проводится время, зачастую менее интуитивны.
В этой статье я обсуждаю два способа повышения производительности: крупномасштабную оптимизацию, например использование кэширования ASP.NET, и мелкомасштабную оптимизацию, которая часто повторяется. Эти небольшие кусочки оптимизации иногда оказываются наиболее интересными. Небольшое изменение, которое вы вносите в свой код, будет вызываться тысячи раз. Оптимизируйте большие фрагменты, и вы можете обнаружить значительный скачок в общей производительности. Оптимизируя небольшими порциями, вы можете сэкономить несколько микросекунд на отдельном запросе, но в совокупности по всем запросам в день вы получите неожиданное улучшение производительности.
Производительность на уровне данных
Когда вы начинаете оптимизировать производительность приложения, есть один решающий тест, который вы можете расставить по приоритетам: нужен ли код доступ к базе данных? Если да, то как часто вы посещаете его? Обратите внимание, что этот тест также можно применить к коду, использующему веб-службы или удаленное управление, но я не буду рассматривать их в этой статье.
Если запрос к базе данных требуется в определенном пути кода в вашем коде, и вы обнаружите другие места, где вы хотите расставить приоритеты для оптимизации, например манипуляции со строками, сначала остановитесь и выполните критические тесты. Если у вас нет действительно серьезной проблемы с производительностью, ваше время будет лучше потрачено на оптимизацию времени, необходимого для подключения к базе данных, объема возвращаемых данных и операций, которые вы выполняете с базой данных и с ней.
Теперь, когда я изложил информацию в целом, давайте рассмотрим 10 советов, которые помогут вашему приложению работать лучше. Начну с тех, которые оказывают наиболее очевидное влияние на повышение производительности.
Совет 1. Возвращайте несколько наборов результатов
Взгляните на код своей базы данных, чтобы узнать, есть ли у вас пути запросов, которые обращаются к базе данных более одного раза. Каждый такой обход уменьшает количество запросов, которые ваше приложение может обслуживать в секунду. Возвращая несколько наборов результатов в одном запросе к базе данных, вы можете сократить общее время, затрачиваемое на обмен данными с базой данных. Уменьшив количество запросов, которые должен обрабатывать сервер базы данных, вы также сделаете свою систему более масштабируемой.
Обычно вы можете использовать операторы динамического SQL для возврата нескольких наборов результатов, я предпочитаю использовать хранимые процедуры. Вопрос о том, стоит ли помещать бизнес-логику в хранимую процедуру, является спорным, но я считаю, что логика в хранимой процедуре может ограничить возвращаемые данные (уменьшает размер набора данных, время, затрачиваемое на сетевое соединение, устраняет необходимость фильтрация данных логического уровня), то это хорошо.
Используя экземпляр SqlCommand и его метод ExecuteReader для создания строго типизированного бизнес-класса, вы можете переместить указатель набора результатов вперед, вызвав NextResult. На рис. 1 показан пример сеанса, в котором определенный класс используется для создания нескольких списков ArrayList. Возврат из базы данных только тех данных, которые вам нужны, значительно уменьшит запросы к памяти на вашем сервере.
1// читаем первый набор результатов
2reader = команда.ExecuteReader();
3
4//прочитайте данные из этого набора результатов
5 while (reader.Read()) {
6 поставщиков.Добавить(PopulateSupplierFromIDataReader(читатель));
7}
8
9// прочитать следующий набор результатов
10читатель.СледующийРезультат();
11
12// читаем данные из второго набора результатов
13 while (reader.Read()) {
14 продуктов.Добавить(PopulateProductFromIDataReader(читатель));
15}
16
17
Совет 2. Доступ к данным с разбивкой на страницы
DataGrid ASP.NET предоставляет замечательные возможности: поддержку подкачки данных. Если в DataGrid настроено разбиение на страницы, одновременно будет отображаться определенное количество результатов. Кроме того, в нижней части DataGrid отображается страничный пользовательский интерфейс для навигации между результатами. Пользовательский интерфейс с разбивкой на страницы позволяет перемещаться вперед или назад по отображаемым данным, отображая определенное количество результатов на странице.
Но есть небольшая проблема. При использовании DataGrid для разбиения по страницам все данные необходимо привязать к таблице. Например, ваш уровень данных должен будет вернуть все данные, а затем DataGrid должен будет заполнить все записи, которые будут отображаться на основе текущей страницы. Если при использовании разбиения на страницы DataGrid возвращается 100 000 записей, на каждый запрос будет отброшено 99 975 записей (при условии, что емкость каждой страницы составляет 25 записей). Когда количество записей растет, производительность приложения сильно снижается, поскольку с каждым запросом необходимо возвращать все больше и больше данных.
Один из способов улучшить код нумерации страниц — использовать хранимые процедуры. На рис. 2 показан пример хранимой процедуры, которая разбивает на страницы таблицу данных Orders в базе данных Nothwind. По сути, все, что вам нужно сделать, это передать индекс страницы и ее емкость. База данных вычисляет соответствующие наборы результатов и возвращает их.
1СОЗДАНИЕ ПРОЦЕДУРЫ Northwind_OrdersPaged
2(
3 @PageIndex целое,
4 @PageSize целое
5)
6АС
7НАЧАЛО
8DECLARE @PageLowerBound int
9DECLARE @PageUpperBound int
10DECLARE @RowsToReturn int
11
12-- Сначала установите количество строк
13SET @RowsToReturn = @PageSize * (@PageIndex + 1)
14SET ROWCOUNT @RowsToReturn
15
16 — Установите границы страницы.
17SET @PageLowerBound = @PageSize * @PageIndex
18SET @PageUpperBound = @PageLowerBound + @PageSize + 1
19
20-- Создайте временную таблицу для хранения выбранных результатов.
21СОЗДАТЬ ТАБЛИЦУ #PageIndex
двадцать два(
23 IndexId int IDENTITY (1, 1) НЕ НУЛЬ,
24 OrderID целое
25)
26
27--Вставка во временную таблицу
28INSERT INTO #PageIndex (OrderID)
29ВЫБРАТЬ
30Идентификатор заказа
31ОТ
32 заказа
33ЗАКАЗАТЬ ПО
34 ИД заказа DESC
35
36 — Возврат общего количества
37ВЫБЕРИТЕ COUNT(OrderID) ИЗ заказов
38
39-- Возврат постраничных результатов
40ВЫБРАТЬ
41 О.*
42ОТ
43 Ордена О,
44 #PageIndex Индекс страницы
45ГДЕ
46 O.OrderID = PageIndex.OrderID И
47 PageIndex.IndexID > @PageLowerBound И
48 PageIndex.IndexID < @PageUpperBound
49ЗАКАЗАТЬ ПО
50 PageIndex.IndexID
51
52КОНЕЦ
53
54
В период общественных работ мы написали элемент управления сервером подкачки для выполнения этой подкачки данных. Вы заметите, что я использовал идею, описанную в совете 1, чтобы вернуть два набора результатов из хранимой процедуры: общее количество записей и запрошенные данные.
Общее количество возвращаемых записей может варьироваться в зависимости от выполненного запроса. Например, предложение WHERE можно использовать для ограничения возвращаемых данных. Мы должны знать общее количество возвращаемых записей, чтобы рассчитать общее количество страниц, отображаемых в пользовательском интерфейсе с разбивкой на страницы. Например, если общее количество записей составляет 1 000 000, а предложение WHERE используется для фильтрации этих записей до 1 000 записей, логике разбиения по страницам необходимо знать общее количество записей, чтобы соответствующим образом отправить пользовательский интерфейс разбиения на страницы.
Совет 3. Пул соединений
Установление TCP-соединения между вашим веб-приложением и SQL Server может оказаться дорогостоящей операцией. Разработчики Microsoft уже некоторое время используют пул соединений, что позволяет им повторно использовать соединения с базами данных. Вместо того, чтобы устанавливать новое TCP-соединение для каждого запроса, новое соединение устанавливается только тогда, когда в пуле соединений нет доступного соединения. Когда соединение закрывается, оно возвращается в пул соединений — оно по-прежнему поддерживает соединение с базой данных, а не полностью разрушает TCP-соединение.
Конечно, нужно быть осторожным с утечками соединений. Всегда закрывайте соединения, когда закончите их использовать. Повторяю: что бы кто-нибудь ни говорил о механизме сборки мусора Microsoft .NET Framework, вы всегда должны явно вызывать метод Close или Dispose в своем соединении, когда закончите с ним. Не доверяйте среде Common Language Runtime (CLR) очистить и закрыть ваше соединение в заранее определенное время. CLR в конечном итоге уничтожит класс и принудительно закроет соединение, но у вас нет гарантии, когда механизм сбора мусора на объекте действительно будет выполнен.
Чтобы добиться наилучших результатов при использовании пула соединений, необходимо соблюдать несколько правил. Сначала откройте соединение, выполните работу, затем закройте соединение. Ничего страшного, если вам придется (желательно применить совет 1) открывать и закрывать соединение несколько раз за запрос, это намного лучше, чем оставлять соединение открытым и передавать его нескольким различным методам. Во-вторых, используйте ту же строку подключения (и, конечно же, тот же идентификатор потока, если вы используете встроенную аутентификацию). Если вы не используете одну и ту же строку подключения, например разные пользовательские строки подключения в зависимости от вошедшего в систему пользователя, вы не получите то же оптимальное значение, которое предоставляет пул соединений. А если вы используете встроенную аутентификацию при выдаче себя за большое количество пользователей, ваш пул соединений также будет гораздо менее эффективным. Счетчики производительности данных .NET CLR могут быть полезны при попытке отследить любые проблемы с производительностью, связанные с объединением пулов соединений.
Всякий раз, когда ваше приложение подключается к ресурсу, например базе данных, или запускается в другом процессе, вы должны делать это, сосредоточив внимание на времени, которое требуется для подключения к ресурсу, времени, необходимом для отправки и получения данных, а также времени, необходимого для подключения к ресурсу. Для отправки и получения данных требуется несколько обращений к базе данных, для которых требуется оптимизация. Оптимизация любого перехода процесса в вашем приложении — это первый шаг на пути к повышению производительности.
Уровень приложения содержит логику, которая подключается к вашему уровню данных и преобразует данные в значимые экземпляры классов и логические процессы. Например, на сервере сообщества здесь вы создаете форум или коллекцию тем и применяете бизнес-правила, такие как разрешения, и, что более важно, здесь выполняется логика кэширования;
Совет 4. API-интерфейс буферизации ASP.NET
Прежде чем приступить к написанию первой строки кода приложения, первое, что следует учитывать, — это спроектировать уровень приложения так, чтобы максимально использовать возможности кэширования ASP.NET.
Если ваш компонент работает в приложении ASP.NET, вы просто ссылаетесь на System.Web.dll в проекте приложения. Если вам необходимо получить доступ к кешу, используйте свойство HttpRuntime.Cache (доступ к этому объекту также можно получить через Page.Cache и HttpContext.Cache).
Существует несколько рекомендаций по использованию кэшированных данных. Во-первых, если данные можно использовать несколько раз, их кэширование — хороший выбор. Во-вторых, если данные общие, а не специфичные для конкретного запроса или пользователя, то их кэширование — отличный вариант. Если данные зависят от пользователя или запроса, но имеют длительный срок хранения, их можно кэшировать, но использовать нечасто. В-третьих, часто упускаемый из виду принцип заключается в том, что иногда можно кэшировать слишком много данных. Обычно на машине x86, чтобы снизить вероятность ошибок нехватки памяти, вам нужно запустить процесс, который использует не более 800 МБ частных байтов. Поэтому кэширование должно быть ограничено. Другими словами, вам может потребоваться повторно использовать результат одного вычисления, но если для этого вычисления требуется десять параметров, вам может потребоваться попытаться кэшировать 10 перестановок, и это может привести к проблемам. Ошибки нехватки памяти из-за чрезмерного кэширования являются наиболее распространенными в ASP.NET, особенно с большими наборами данных.
Кэширование имеет несколько замечательных функций, о которых вам нужно знать. Во-первых, в кэше реализован наименее используемый алгоритм, позволяющий ASP.NET принудительно очищать кэш — автоматически удаляя неиспользуемые элементы из кэша — когда память работает менее эффективно. Во-вторых, кеш поддерживает просроченные зависимости, срок действия которых может быть истечен принудительно. Эти зависимости включают время, ключи и файлы. Часто используется время, но в ASP.NET 2.0 представлен новый, более мощный тип инвалидации: инвалидация кэша базы данных. Это относится к автоматическому удалению элементов в кэше при изменении данных в базе данных. Дополнительные сведения о признании недействительными кэша базы данных см. в колонке Dino Esposito Cutting Edge в июльском выпуске журнала MSDN Magazine за 2004 г. Чтобы понять архитектуру кэша, см. рисунок 3.
Совет 5 — Кеширование по запросу
Ранее в этой статье я упоминал, что небольшие улучшения в часто используемых путях кода могут привести к значительному общему приросту производительности. Из этих небольших улучшений одно определенно мне больше всего нравится, и я называю его кэшированием по запросу.
API-интерфейсы кэширования предназначены для кэширования данных в течение более длительного периода времени или до тех пор, пока не будут выполнены определенные условия, но кэширование каждого запроса означает кэширование данных только на время этого запроса. Для каждого запроса часто осуществляется доступ к определенному пути кода, но данные извлекаются, применяются, изменяются или обновляются только один раз. Это звучит немного теоретически, поэтому давайте приведем конкретный пример.
В приложении форума сервера сообщества каждому серверному элементу управления, используемому на странице, требуются данные персонализации, чтобы определить, какой внешний вид использовать, какую таблицу стилей использовать, а также другие данные персонализации. Некоторые из этих данных могут кэшироваться на длительный срок, но некоторые данные извлекаются только один раз за запрос, а затем повторно используются несколько раз во время этого запроса, например, для появления элемента управления.
Чтобы добиться кэширования каждого запроса, используйте ASP.NET HttpContext. Для каждого запроса создается экземпляр HttpContext, доступный из любого места свойства HttpContext.Current во время запроса. Класс HttpContext имеет специальное свойство коллекции Items; объекты и данные, добавляемые в эту коллекцию Items, кэшируются только на время выполнения запроса. Точно так же, как вы можете использовать кеширование для хранения часто используемых данных, вы также можете использовать HttpContext.Items для хранения данных, которые используются только для каждого запроса. Логика этого очень проста: данные добавляются в коллекцию HttpContext.Items, когда она не существует, а при последующих поисках возвращаются только данные из HttpContext.Items.
Совет 6 — Фоновая обработка
Путь к коду должен быть максимально быстрым, верно? Могут быть случаи, когда вы обнаружите, что выполняете очень ресурсоемкую задачу, которая выполняется при каждом запросе или каждые n запросов. Отправка электронных писем или анализ и проверка входящих данных — вот некоторые примеры.
При анализе форумов ASP.NET 1.0 и перепроектировании контента, составляющего сервер сообщества, мы обнаружили, что путь кода для публикации новых сообщений был чрезвычайно медленным. Каждый раз, когда публикуется новое сообщение, приложению сначала необходимо убедиться в отсутствии дублирующихся сообщений, затем оно должно проанализировать сообщение с помощью фильтра «плохих слов», проанализировать смайлики персонажей сообщения, пометить и проиндексировать сообщение, а также добавить опубликуйте сообщение по запросу, добавьте его в соответствующую очередь, проверьте вложение и, наконец, отправьте уведомление по электронной почте всем подписчикам сразу после публикации сообщения. Очевидно, что здесь задействовано очень многое.
После исследования выяснилось, что большая часть времени тратилась на логику индексации и отправку электронных писем. Индексирование сообщений — очень трудоемкая операция, и было обнаружено, что встроенная функция System.Web.Mail подключается к SMTP-серверу, а затем непрерывно отправляет электронные письма. По мере увеличения количества подписчиков на определенную публикацию или тематическую область выполнение функции AddPost занимает все больше и больше времени.
Индексирование электронной почты не требуется для каждого запроса. В идеале мы хотели бы выполнить эту операцию в пакетном режиме, индексируя 25 сообщений за раз или отправляя все электронные письма каждые пять минут. Мы решили использовать код, который я использовал для создания прототипа инвалидации кэша данных, который в конечном итоге был включен в Visual Studio 2005.
Класс Timer в пространстве имен System.Threading очень полезен, но не очень известен в .NET Framework, по крайней мере, среди веб-разработчиков. После создания этот класс Timer будет вызывать указанный обратный вызов с настраиваемым интервалом для потока в ThreadPool. Это означает, что вы можете настроить выполнение своего кода без входящих запросов к приложению ASP.NET, что идеально подходит для фоновой обработки. В этом фоновом процессе вы также можете выполнять такие операции, как индексирование или отправка электронных писем.
Однако у этой технологии есть несколько проблем. Если домен приложения удален, этот экземпляр таймера перестанет генерировать события. Кроме того, поскольку в CLR существует жесткий стандарт количества потоков на процесс, на сильно загруженном сервере может возникнуть ситуация, когда таймер не может гарантировать, что потоки продолжат завершать операцию, и в некоторой степени может вызвать задержки. . ASP.NET пытается свести к минимуму вероятность этого, сохраняя определенное количество потоков, доступных в процессе, и используя только часть общего числа потоков для обработки запросов. Однако это может стать проблемой, если у вас много асинхронных операций.
Здесь недостаточно места для этого кода, но вы можете скачать простой для понимания пример на сайте www.rob-howard.net . Ознакомьтесь со слайдами и демонстрациями презентации Blackbelt TechEd 2004.
Совет 7 — Кэширование вывода страниц и прокси-серверы
ASP.NET — это ваш уровень представления (или должен быть вашим уровнем представления); он состоит из страниц, пользовательских элементов управления, серверных элементов управления (HttpHandlers и HttpModules) и контента, который они генерируют. Если у вас есть страница ASP.NET, которая генерирует выходные данные (HTML, XML, изображения или любые другие данные), и когда вы запускаете этот код при каждом запросе, он генерирует один и тот же результат, тогда у вас есть инструмент, который можно использовать для отличная альтернатива кэшированию вывода страниц.
Добавив следующую строку вверху страницы:
<%@ Page OutputCache VaryByParams="none" Duration="60" %>
Вы можете эффективно сгенерировать выходные данные для этой страницы один раз, а затем повторно использовать их несколько раз в течение до 60 секунд, после чего страница будет выполнена повторно, а выходные данные снова будут добавлены в кеш ASP.NET. Этого поведения также можно добиться с помощью некоторых программируемых API низкого уровня. Существует несколько настраиваемых параметров кэширования вывода, например только что упомянутое свойство VaryByParams. VaryByParams просто запрашивается, но также позволяет указать параметры HTTP GET или HTTP POST для изменения записей кэша. Например, просто установите VaryByParam="Report" для кэширования вывода для default.aspx?Report=1 или default.aspx?Report=2. Дополнительные параметры можно указать, указав список, разделенный точкой с запятой.
Многие люди не осознают, что при использовании кэширования вывода страницы ASP.NET также генерируют HTTP-заголовки, которые передаются на серверы кэширования, например те, которые используются Microsoft Internet Security and Acceleration Server или Akamai. После установки заголовка таблицы кэша HTTP документы могут кэшироваться на этих сетевых ресурсах, а запросы клиентов могут удовлетворяться без возврата на исходный сервер.
Таким образом, использование кэширования вывода страниц не повысит эффективность вашего приложения, но может снизить нагрузку на сервер, поскольку нисходящая технология кэширования кэширует документ. Конечно, это может быть только анонимный контент; как только он перейдет в нисходящий поток, вы больше никогда не увидите запросы и больше не сможете выполнять аутентификацию, чтобы предотвратить доступ к нему.
Совет 8. Запустите IIS 6.0 (даже просто для использования кеша ядра)
Если вы не используете IIS 6.0 (Windows Server 2003), вы упускаете некоторые значительные улучшения производительности веб-серверов Microsoft. В совете 7 я обсуждал кэширование вывода. В IIS 5.0 запросы проходят через IIS, а затем в ASP.NET. Когда дело доходит до кэширования, HttpModule в ASP.NET получает запрос и возвращает содержимое кэша.
Если вы используете IIS 6.0, вы обнаружите небольшую приятную функцию, называемую кэшем ядра, которая не требует каких-либо изменений кода в ASP.NET. Когда ASP.NET выполняет запрос на кэширование вывода, кэш ядра IIS получает копию кэшированных данных. Когда запрос поступает от сетевого драйвера, драйвер уровня ядра (без переключения контекста в пользовательский режим) получает запрос, сбрасывает кэшированные данные в ответ, если они кэшированы, а затем завершает выполнение. Это означает, что при использовании кэширования в режиме ядра с кэшированием вывода IIS и ASP.NET вы увидите невероятные результаты в производительности. Во время разработки ASP.NET в Visual Studio 2005 я был менеджером по разработке, ответственным за производительность ASP.NET. Разработчики выполняют конкретную работу, но я вижу всю отчетность, которая поступает каждый день. Результаты кэширования режима ядра всегда наиболее интересны. Наиболее распространенной характеристикой является то, что сеть переполнена запросами/ответами, в то время как IIS работает с загрузкой ЦП лишь около 5%. Это шокирует! Конечно, есть и другие причины использовать IIS 6.0, но кэширование в режиме ядра является наиболее очевидным.
Совет 9 — Используйте сжатие Gzip
Хотя использование gzip не обязательно снижает производительность сервера (поскольку вы можете заметить увеличение загрузки ЦП), использование сжатия gzip может уменьшить количество байтов, отправляемых сервером. Это приводит к ощутимому увеличению скорости страницы и снижению использования полосы пропускания. В зависимости от отправляемых данных, насколько они могут быть сжимаемыми и поддерживает ли их браузер клиента (IIS будет отправлять содержимое, сжатое с помощью gzip, только клиентам, которые поддерживают сжатие gzip, например Internet Explorer 6.0 и Firefox), ваш сервер может обслуживать Подробнее запросы. Фактически, почти каждый раз, когда вы уменьшаете объем возвращаемых данных, вы увеличиваете количество запросов в секунду.
Сжатие Gzip встроено в IIS 6.0, и его производительность намного выше, чем сжатие gzip, используемое в IIS 5.0, что является хорошей новостью. К сожалению, при попытке включить сжатие gzip в IIS 6.0 вы не сможете найти этот параметр в диалоговом окне «Свойства» IIS. Команда IIS встроила в сервер отличную функциональность gzip, но забыла включить административный интерфейс для ее включения. Чтобы включить сжатие gzip, вам придется покопаться в настройках конфигурации XML IIS 6.0 (чтобы не потерять сердце). Кстати, спасибо Скотту Форсайту из OrcsWeb за то, что он помог мне поднять эту проблему с сервером www.asp.net , размещенным на OrcsWeb.
В этой статье не описываются эти шаги. Прочтите статью Брэда Уилсона на сайте IIS6 Compression. Также имеется статья базы знаний о включении сжатия для ASPX в разделе Включение сжатия ASPX в IIS. Однако следует отметить, что из-за некоторых особенностей реализации динамическое сжатие и кэширование ядра не могут существовать одновременно в IIS 6.0.
Совет 10 — Состояние представления управления сервером
Состояние просмотра — интересное название для ASP.NET, которое хранит некоторые данные о состоянии в скрытых полях вывода сгенерированной страницы. Когда страница отправляется обратно на сервер, сервер может анализировать, проверять и применять эти данные состояния просмотра обратно в дерево управления страницей. Состояние просмотра — очень мощная функция, поскольку она позволяет сохранять состояние на клиенте и не требует использования файлов cookie или памяти сервера для сохранения этого состояния. Многие серверные элементы управления ASP.NET используют состояние просмотра для сохранения параметров, созданных во время взаимодействия с элементами страницы, например для сохранения текущей страницы, которая отображается при разбиении данных на страницы.
Однако использование состояния просмотра также имеет некоторые недостатки. Во-первых, это увеличивает общую нагрузку на страницу при ее обслуживании или запросе. Дополнительные издержки также возникают при сериализации или десериализации данных состояния представления, отправляемых обратно на сервер. Наконец, состояние просмотра увеличивает выделение памяти на сервере.
Некоторые серверные элементы управления имеют тенденцию чрезмерно использовать состояние представления, даже если оно не нужно, наиболее заметным из которых является DataGrid. По умолчанию свойство ViewState включено, но вы можете отключить его на уровне элемента управления или страницы, если оно вам не нужно. Внутри элемента управления просто установите для свойства EnableViewState значение false или установите его глобально на странице, используя следующий параметр:
<%@ Страница EnableViewState="false" %>
Если вы не отправляете страницу обратно или всегда повторно создаете элементы управления на странице при каждом запросе, вам следует отключить состояние просмотра на уровне страницы.
краткое содержание
Я дал вам несколько советов, которые считаю полезными при написании высокопроизводительных приложений ASP.NET. Как я упоминал ранее в этой статье, это предварительное руководство, а не последнее слово о производительности ASP.NET. (Информацию об улучшении производительности приложений ASP.NET см. в разделе Улучшение производительности ASP.NET.) Лучший способ решить конкретную проблему с производительностью можно найти только на основе собственного опыта. Тем не менее, эти советы должны дать вам хорошее руководство в вашем путешествии. В разработке программного обеспечения есть несколько абсолютов; каждое приложение уникально.
См. врезку «Распространенные мифы о производительности».
Роб Ховард — основатель компании Telligent Systems, специализирующейся на высокопроизводительных веб-приложениях, управлении базами знаний и системах совместной работы. Ранее Роб работал в Microsoft, где помогал проектировать инфраструктуру для ASP.NET 1.0, 1.1 и 2.0. Чтобы связаться с Робом, посетите [email protected] .
Исходная ссылка: http://msdn.microsoft.com/msdnmag/issues/05/01/ASPNETPerformance/default.aspx.