Asp кэшируйте часто используемые данные в объектах application или session


Содержание

Кэш данных и объект сеанса в ASP.Net

Должны ли храниться динамические бизнес-объекты для сайта в сеансе пользователей или использовать кэширование ASP.Net(такие объекты, как заказы, информация профиля и т.д.)?

Я работал с сайтами, которые использовали сеансы для хранения бизнес-объектов, но мне было интересно. Каковы преимущества или недостатки кеширования?

Если объекты разделяются между сеансами пользователя, используйте кеш. Если объекты уникальны для каждого сеанса, возможно, потому, что они управляются разрешениями, а затем сохраняйте их в сеансе. Сам процесс in-process хранится в кеше, поэтому решающим фактором действительно должна быть область данных.

Кэширование — это просто кеширование. Вы никогда не можете опираться на записи, поэтому нет никаких предположений в этом отношении: будьте готовы перейти непосредственно к БД (или где-либо еще), чтобы восстановить данные.

С другой стороны, сеанс больше подходит для хранения объектов, хотя лично я стараюсь избегать хранения сеанса в пользу БД. Обычно я делаю это, абстрагируя хранилище за непрозрачным интерфейсом ISessionStoreService:

а затем «соответствующая реализация зависимостей», будь то InmemorySessionStore, DbSessionStore или что-то еще.

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

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

Объекты сеанса подходят для пользовательских данных, с другой стороны, объекты кэша более подходят для данных, общих для приложения.
Ключом к сохранению в том или ином случае является определение того, какие именно вы пытаетесь сохранить, будут ли данные, доступные пользователю, или их необходимо использовать во всех приложениях.

Session = > Веб-страница с пошаговым интерфейсом (например, онлайн-тест).
Cache = > Информация, отображаемая в виде своего рода виджета погоды (например, того, что у Google на странице igoogle.com).
Надеюсь, это поможет.

Хотя вы можете сохранить свой бизнес-объект в кеше, но Cache предназначен для повышения производительности, а не для управления штатами. Представьте, что у вас есть процесс получения 1000 записей из базы данных (и это занимает около 3 секунд), и вам понадобится это на несколько минут. Вы можете хранить свои объекты в кеше и устанавливать дату истечения срока действия, приоритет и зависимость от него (например, SqlDependency или FileDependency), поэтому для следующих запросов вы можете использовать данные Cached вместо их извлечения из базы данных. Вы можете сохранить свой объект в сеансе, но вы не можете установить зависимость для сеанса по умолчанию. Также у Cache есть уникальное поведение, которое, когда система нуждается в памяти, будет освобождать объекты из кеша в зависимости от его приоритета. Объекты кэша являются глобальными для Приложения и распределяются между всеми пользователями, но сеанс не используется совместно и используется для каждого пользователя (сеанса).

Как хранить (кэшировать?) Данные между несколькими сессиями в ASP.NET

Я пишу приложение веб-формы C # ASP.NET. Короче говоря, это приложение извлекает данные с сервера и отображает их для пользователей.

Чтобы получить доступ к этому серверу, мое приложение должно сгенерировать информацию для входа. Создание информации для входа занимает несколько минут. Эта информация для входа в систему меняется ежедневно, но она одинакова для всех, кто использует мое приложение (в определенный день).

Мое приложение будет ежедневно использоваться сотнями людей. Глупо заставлять каждого пользователя ждать несколько минут для получения информации для входа в систему.

В идеале я хотел бы собирать информацию для входа один раз в день и сохранять результаты где-нибудь на моем сервере.

Какие-нибудь советы? Я знаю, что в .NET есть Cache и Session , но они хранят данные только для одного отдельного пользователя. Есть ли у вас какие-либо методы для хранения этой информации для входа в систему, чтобы я мог получить ее из своего кода?

1 ответ

Вы не правы, кеш работает на уровне приложения, а не на уровне пользователя, от MSDN

Приложение может часто повышать производительность, сохраняя данные в памяти, к которой часто обращаются, и для создания которой требуется значительное время обработки. Например, если ваше приложение обрабатывает большие объемы данных, используя сложную логику, а затем возвращает данные в виде отчета, к которому часто обращаются пользователи, эффективно избегать повторного создания отчета каждый раз, когда пользователь запрашивает его. Точно так же, если ваше приложение содержит страницу, которая обрабатывает сложные данные, но обновляется редко, для сервера неэффективно пересоздавать эту страницу при каждом запросе.

Чтобы помочь вам повысить производительность приложений в этих ситуациях, ASP.NET обеспечивает кэширование с использованием двух основных механизмов кэширования. Первый — это кэширование приложения, которое позволяет вам кэшировать сгенерированные вами данные, такие как объект DataSet или бизнес-объект настраиваемого отчета. Второй — кэширование вывода страницы, которое сохраняет результаты обработки страницы и повторно использует выходные данные вместо повторной обработки страницы, когда пользователь снова запрашивает страницу.

Я думаю, что Application cache подходит лучше, чем другой

О Expire

Есть два способа управления им, вы можете установить X минут как предел, а затем установить, если хотите:

Абсолют : истечение срока действия данных через X минут с момента создания объекта

Абсолютное истечение срока действия: в этом примере данные в кеше будут кэшироваться в течение одной минуты, после чего срок действия кэша истечет. Обратите внимание, что абсолютное истечение и скользящее истечение (ниже) не могут использоваться вместе.

Скольжение : срок действия данных истекает через X минут с момента последнего использования объекта кэша.

Срок действия слайда: в этом примере будут кешироваться некоторые часто используемые данные. Данные будут оставаться в кэше до тех пор, пока не пройдет одна минута, и на них ничего не будет ссылаться. Обратите внимание, что скользящее истечение и абсолютное истечение не могут использоваться вместе.

Управление состоянием приложения¶

В ASP.NET Core статусом приложения можно управлять разными способами. В этой статье мы рассмотрим некоторые варианты, а также установим и настроим поддержку состояния сессий в приложениях ASP.NET Core.

Опции Application State¶

Application state (состояние приложения) касается всех данных, которые используются для представления текущего состояния приложения. Это касается и глобальных, и конкретных данных. В предыдущих версиях ASP.NET (и даже ASP) имелась встроенная поддержка глобальных хранилищ состояний Application и Session , а также некоторые другие опции.

У хранилища Application были почти такие же характеристики, что и у ASP.NET Cache . В ASP.NET Core Application больше не существует; приложения, написанные для предыдущих версий ASP.NET и перемещенные в ASP.NET Core заменяют Application реализацией Caching .

Разработчики приложений вольны использовать различные провайдеры состояний приложений в зависимости от разных факторов:

  • Как долго должны существовать данные?
  • Какова величина данных?
  • Каков формат этих данных?
  • Можно ли их сериализовать?
  • Насколько чувствительны данные? Могут ли они храниться на стороне клиента?


В зависимости от ответов на эти вопросы состояние приложения ASP.NET Core может управляться разными способами.

HttpContext.Items¶

Коллекция Items — это лучшее место для хранения данных, которые нужны для обработки определенного запроса. Их содержание сбрасывается после каждого запроса. Это что-то вроде связки между компонентами и middleware, которые работают на разных этапах запроса и не имеют прямого отношения к данным, передающим параметры и возвращаемые значения. См. Работа с HttpContext.Items.

Строка запроса и Post¶

Состояние запроса может быть передано другому запросу, если вы добавите значение строке нового запроса или используете POST. Такие технологии не нужно использовать с чувствительными данными, поскольку здесь данные отправляются клиенту, а затем обратно серверу. Лучше всего использовать такой способ с небольшим количеством данных. Строки запросов особенно полезны для определения состояния постоянным образом, и таким образом создаются ссылки, сохраняющие состояние, а затем они отправляются через имейлы или социальные сети для возможного дальнейшего использования. Поскольку URL со строками запросов можно легко делиться, вы должны позаботиться об избежании CSRF-атак) (например, даже если предположить, что только зарегистрированные пользователи могут выполнять некоторые действия с помощью таких URL, атакующий может попробовать использовать такой URL как зарегистрированный пользователь).

Некоторое количество данных, связанных с состоянием, может быть сохранено в куки. Они отправляются с каждым запросом, так что их размер должен быть минимальным. В идеале, нужно использовать только идентификатор с актуальными данными, сохраненными на сервере, которые связаны с идентификатором.

Сессия¶

Сессионное хранилище использует куки-идентификатор, чтобы получить доступ к данным, связанным с определенной сессией браузера (серией запросов от определенного браузера). Вы не должны думать, что сессия ограничена одним пользователем, так что аккуратно храните информацию в разделе Session. Это хорошее место для хранения состояния приложения, которое касается определенной сессии, но которое не нужно отслеживать постоянно (или которое можно восстановить из хранилища состояний). См. Установка и настройка сессий.

Кэширование помогает сохранить и эффективно извлекать произвольные данные приложения, основываясь на ключах, определенных разработчиком. Здесь есть правила по истекающим кэшированным элементам, и это зависит от временных и других условий. См. Caching .

Конфигурация¶

Конфигурация может считаться некоторой формой хранилища данных приложения, хотя обычно во время запуска приложения она является read-only. См. Конфигурация .

Другие постоянные хранилища¶

Другие постоянные хранилища, например, Entity Framework и база данных или Azure Table Storage также могут служить для сохранения состояния приложения, но ASP.NET напрямую их не поддерживает.

Работа с HttpContext.Items¶

HttpContext поддерживает коллекцию типа IDictionary object> , которая называется Items . Эта коллекция доступна при запуске HttpRequest` и сбрасывается в конце каждого запроса. Вы можете получить к ней доступ при помощи запроса или присвоения значения ключу.

Например, Связующее ПО (Middleware) может что-то добавить в коллекцию Items :

и далее в потоке другой кусок связующего ПО может добраться до этого:

Ключи в Items являются простыми строками, и если вы разрабатываете связующее ПО, которое должно работать с несколькими приложениями, вам стоит добавить ключам уникальный идентификатор, чтобы избежать проблем с ключами (например, “MyComponent.isVerified” вместо “isVerified”).

Установка и настройка сессий¶

В ASP.NET Core есть пакет, который предоставляет связующее ПО для управления состоянием приложения. Вы можете установить его, добавив ссылку на пакет в файл project.json.

После установки пакета нужно настроить Session в классе Startup . Session создается вверху IDistributedCache , так что вам нужно настроить все это, иначе вы получите ошибку.

Если вы не настроите хотя бы одну реализацию IDistributedCache , у вас появится исключение “Unable to resolve service for type ‘Microsoft.Extensions.Caching.Distributed.IDistributedCache’ из-за попытки активировать ‘Microsoft.AspNet.Session.DistributedSessionStore’.”

ASP.NET поставляется с несколькими реализациями IDistributedCache , включая опцию in-memory (используется только во время разработки и тестирования). Чтобы настроить сессию при помощи этой опции, добавьте Microsoft.Extensions.Caching.Memory в пакет project.json, а следующее в ConfigureServices :

Затем добавьте следующее в Configure перед app.UseMVC() , и вы будете готовы использовать сессию:

После установки и настройки вы будете готовы использовать Session из HttpContext .

Если вы попытаетесь использовать Session перед вызовом UseSession , у вас появится исключение InvalidOperationException , что будет написано следующее: “Session has not been configured for this application or request.”

Если вы попытаетесь создать новую Session (пока не было создано куки сессии) после того, как вы начали создавать поток Response , у вас также появится исключение InvalidOperationException , где будет говорится, что “The session cannot be established after the response has started”. Это исключение, возможно, не будет отображено в браузере; вам потребуется просмотреть серверный лог, чтобы найти его:

Детали реализации¶

Сессия использует куки, чтобы отслеживать и устранять неоднозначные моменты между запросами с разных браузеров. По умолчанию этот куки называется ”.AspNet.Session”. Далее, по умолчанию этот куки не указывает домен, и он недоступен для скриптов на клиентской стороне (поскольку CookieHttpOnly установлен на true ).

IdleTimeout (используется на сервере независимо от куки) можно переписать при настройке Session при помощи SessionOptions :

IdleTimeout используется сервером для определения того, когда сбрасывается сессия. Каждый запрос передается связующему ПО Session (независимо от того, считывается или записывается Session внутри данного ПО), и это сбрасывает таймаут. Обратите внимание, что все это происходит независимо от сброса куки.

Если два запроса пытаются изменить контекст сессии, сделает это последний. Кроме того, все виды контекста сессии сохраняются совместно. Это обозначает, что если два запроса меняют различные части сессии (разные ключи), они будут все равно влиять друг на друга.

ISession¶

После установки и настройки сессии вы ссылаетесь на нее через HttpContext, который предоставляет свойство Session типа ISession. Вы можете использовать этот интерфейс, чтобы получать и устанавливать значения в Session , в качестве byte[] .


Поскольку Session создается вверху IDistributedCache , вы всегда должны сериализовать сохраняемые экземпляры объекта. Интерфейс работает с byte[] , а не просто с object . Однако существуют методы расширения, которые упрощают работу с простыми типами, такими как String и Int32 , а также упрощают получение значений byte[] из сессии.

Если вы сохраняете более сложные объекты, вам нужно сериализовать объект в byte[] , чтобы его сохранить, а при получении десериализовать его.

Рабочий пример использования сессии¶

В данном примере показано, как работать с Session, включая сохранение и получение простых типов, а также пользовательских объектов. Если вы хотите узнать, что происходит после истечения сессии, то вы увидите это на данном примере, поскольку сессия длится всего 10 секунд:

Когда вы впервые переходите на веб сервер, тут представлен скриншот, показывающий, что сессия еще не была установлена:

Такое поведение по умолчанию происходит из-за связующего ПО в Startup.cs , который запускается тогда, когда делается запрос, у которого нет установленной сессии (обратите внимание на выделенные сессии):

GetOrCreateEntries — это вспомогательный метод, который получает экземпляр RequestEntryCollection из Session , если сессия существует; в ином случае он создает коллекцию и возвращает ее. Коллекция содержит экземпляры RequestEntry , в которых находятся различные запросы, которые сделал пользователь во время текущей сессии.

Типы, которые хранятся в сессии, помечаются [Serializable] .

Извлечение текущего экземпляра RequestEntryCollection происходит при помощи вспомогательного метода GetOrCreateEntries :

Если в Session существует объект, он извлекается как тип byte[] , а затем десериализуется с помощью MemoryStream и BinaryFormatter . Если объект не находится в Session , метод извлекает новый экземпляр RequestEntryCollection .

В браузере нажатие гиперссылки “Establish session” направляет запрос по пути “/session” и возвращает такой результат:

Обновление страницы включает счетчик; возврат к корню сайта (после нескольких запросов) имеет вот такой итог, то есть, здесь подсчитаны все запросы, которые были сделаны во время этой сессии:

Работа с сессиями происходит с помощью связующего ПО, которое направляет запросы на “/session”:

Запросы по этому пути получат или создадут RequestEntryCollection , добавят к ней текущий путь, а затем сохранят сессию с помощью вспомогательного метода SaveEntries :

SaveEntries показывает, как превратить пользовательский объект в byte[] для сохранения в Session с помощью MemoryStream и BinaryFormatter .

Пример включает в себя некоторое связующее ПО, которое стоит упомянуть, и оно работает с путем “/untracked”. Вот его настройки:

Asp кэшируйте часто используемые данные в объектах application или session

Обновлен: Ноябрь 2007

Часто приложение может повысить производительность с помощью хранения в памяти часто используемых данных, для создания которых требуется довольно долгое время обработки. Например, если приложение обрабатывает большие объемы данных, используя сложную логику, и затем возвращает данные в качестве отчета, к которому часто обращаются пользователи, будет эффективней избегать повторного создания отчета каждый раз, когда его запрашивает пользователь. Аналогично, если приложение содержит редко обновляющуюся страницу, обрабатывающую сложные данные, создавать эту страницу заново при каждом обращении будет неэффективно.

Илон Маск рекомендует:  RemoveDir - Функция Delphi

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

Кэш приложения предоставляет программный способ хранения произвольных данных в памяти с помощью пар «ключ-значение». Использование кэша приложения похоже на использование состояния приложения. Однако в отличие от состояния приложения, данные в кэше приложения изменяемы, что означает, что они не сохраняются в памяти в течение всего времени работы приложения. Преимущество использования кэша приложения состоит в том, что кэшем управляет платформа ASP.NET — она убирает элементы, когда истекает их срок действия, когда они становятся недействительны, или же когда остается мало памяти. Кэш приложения также может быть настроен для предупреждения приложения об удалении элемента. Дополнительные сведения см. в разделе Кэширование данных приложения .

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

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

Кэш вывода страницы предоставляет два метода кэширования страницы: полное кэширование страницы и частичное кэширование страницы. Полное кэширование страницы позволяет сохранить все части страницы в памяти и использовать их для выполнения запроса клиента. Частичное кэширование страницы позволяет сохранить одни части страницы в кэше, в то время как другие части страницы остаются динамическими. Дополнительные сведения см. в разделе Кэширование страниц ASP.NET .

Частичное кэширование страницы может выполняться двумя способами: кэширование элементов управления и подстановка после кэширования. Кэширование элементов управления, также иногда называемое фрагментарным кэшированием, позволяет сохранять в кэше часть вывода страницы путем включения информации в пользовательский элемент управления и пометки пользовательского элемента как кэшируемого. Это позволяет кэшировать часть содержимого внутри страницы, в то время как вся страница целиком не кэшируется и каждый раз создается заново. Например, при создании страницы, отображающей большой объем динамического содержимого, такого как биржевая информация, но имеющей при этом статичные части, такие как итоги по торгам за неделю, можно поместить статичные части в пользовательские элементы и позволить им кэшироваться.

Подстановка после кэширования является противоположным по своему действию методом. Вся страница кэшируется, однако фрагменты страницы остаются динамическими. Например, если создать страницу, которая является статической в течение заданного периода времени, можно указать, что вся страница должна быть помещена в кэш. При добавлении на страницу элемента управления Label , который отображает имя пользователя, элемент управления Label будет оставаться одним и тем же при каждом обновлении страницы и для каждого пользователя, отображая имя пользователя, запросившего страницу перед ее кэшированием. Тем не менее, при использовании подстановки после кэширования всю страницу можно поместить в кэш, но при этом отметить отдельные части страницы как некэшируемые. В таком случае можно добавить элементы управления Label в некэшируемую часть, и они будут создаваться динамически для каждого пользователя при каждом запросе страницы. Дополнительные сведения см. в разделе Кэширование частей страницы ASP.NET .

Кэширование страниц на основе параметров запроса

В дополнение к кэшированию единственной версии страницы кэширование вывода страницы ASP.NET предоставляет возможности по созданию нескольких версий страницы, различающихся по параметрам запроса. Дополнительные сведения см. в разделе Кэширование нескольких версий страницы .

Платформа ASP.NET может удалить данные из кэша по одной из следующих причин:

На сервере не хватает памяти (этот процесс называется очисткой).

Истек срок действия элемента в кэше.

Изменилась зависимость элемента.

Упрощая управление кэшированными элементами, платформа ASP.NET может уведомлять приложение об удалении элементов из кэша.

Очистка

Очистка — это процесс удаления элементов из кэша при нехватке памяти. Элементы удаляются, если к ним долгое время не было обращений, или же если элементы при добавлении в кэш были помечены как низкоприоритетные. Для определения тех элементов, которые нужно удалить в первую очередь, ASP.NET использует объект CacheItemPriority . Дополнительные сведения см. в разделе Практическое руководство. Добавление элементов в объект Cache .


Истечение срока действия

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

Тип срока действия

Скользящий срок действия

Определяет срок действия элемента со времени последнего обращения. Например, можно задать истечение срока действия элемента спустя 20 минут после последнего обращения к нему в кэше.

Абсолютный срок действия

Определяет срок действия предмета независимо от частоты обращений. Например, можно задать истечение срока действия элемента в 18:00 или же спустя четыре часа.

Зависимости

Можно настроить срок хранения элемента в кэше в зависимости от других элементов приложения, таких как файлы или базы данных. При изменении элемента, от которого зависит элемент в кэше, ASP.NET удаляет элемент из кэша. Например, если веб-узел отображает отчет, созданный приложением по XML-файлу, можно поместить данный отчет в кэш и настроить его так, чтобы он зависел от XML-файла. Когда XML-файл будет изменен, ASP.NET удалит отчет из кэша. Когда код запросит отчет, код сначала определит, находится ли отчет в кэше, и если нет — код создаст его. Таким образом, всегда будет доступна самая последняя версия отчета.

Кэш ASP.NET поддерживает зависимости, описанные в следующей таблице.

Зависимость по ключу

Элементы в кэше приложения хранятся в парах «ключ-значение». Зависимость по ключу позволяет элементу зависеть от ключа другого элемента в кэше приложения. Когда исходный элемент удаляется, удаляется также и элемент, имеющий зависимость по ключу. Например, можно добавить в кэш элемент с именем ReportsValid и кэшировать несколько отчетов, зависимых от ключа ReportsValid . Когда элемент ReportsValid будет удален из кэша, все зависимые кэшированные отчеты также будут удалены из кэша.

Зависимость от файла

Элемент в кэше зависит от внешнего файла. Если файл изменится или будет удален, кэшированный элемент будет удален.

Зависимость от SQL

Элемент в кэше зависит от изменений в таблице базы данных Microsoft SQL Server 2005, SQL Server 2000 или SQL Server 7.0. В случае SQL Server 2005 элемент может зависеть от строки в таблице. Дополнительные сведения см. в разделе Кэширование в ASP.NET с помощью класса SqlCacheDependency .

Зависимость от статистического выражения

Элемент в кэше зависит от нескольких элементов; зависимость при этом задается с помощью класса AggregateCacheDependency . Если зависимости будут каким-либо образом изменены, элемент будет удален из кэша.

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

Приложение может получать уведомления об удалении элемента из кэша приложения. Например, если имеется элемент, требующий для создания большое количество времени обработки, уведомления о его удалении из кэша можно использовать для того, чтобы немедленно заменить его. В результате в следующий раз при запросе элемента пользователю не придется ждать обработки элемента. Дополнительные сведения см. в разделе Практическое руководство. Уведомление приложения об удалении элемента из кэша .

Лучшие практики для увеличения производительности ASP.NET Core приложений

Всегда используйте последнюю версию ASP.NET Core и nuget пакетов

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

Примечание в статье часто используется понятие ‘Hot code path’. Под этим имеется ввиду место в вашем коде которое очень долго выполняется.

Используйте кэширование

Мы можем повысить производительность приложения, если сможем каждый раз уменьшать количество запросов к серверу. Это не означает, что вы не будете делать запросы на сервер вовсе, это только означает, что вы не будете делать запросы на сервер КАЖДЫЙ РАЗ. В первый раз вы сделаете запрос на сервер и получите ответ, и этот ответ будет храниться где-то на будущее в течение некоторого времени (конечное количество времени, например 90 минут), и в следующий раз, когда вы сделаете реквест на тот же эндпоинт, сначала вы проверите, если у вас уже есть данные которые где-то сохранены, и если да, то вы будете использовать сохраненные данные вместо того, чтобы делать вызов серверу.

Кэширование бывает нескольких типов:

Кэширование ответов на основе HTTP

Устанавливается заголовком Cache-Control

Распределенный кэш

Используйте распределенный кэш для хранения данных к которым нужен быстрый доступ. Кэширование с помощью сторонних библиотек Например Redis Cache

Кэширование в памяти

Кэширование в памяти использует память сервера для хранения кэшированных данных. Этот тип кэширования подходит для одного или нескольких серверов.

Cache Tag Helper

Используйте cache tag helper в MVC приложениях, например:

Distributed Cache Tag Helper


Можно использовать Cache Tag Helper более широко и сохранять этот кэш например в Redis или SQL Server. В ASP.NET Core есть две встроенные реализации интерфейса IDistributedCache. Одна из них основана на SQL Server services.AddDistributedSqlServerCache , а другая — на Redis services.AddStackExchangeRedisCache.

Redis Cache

Когда мы работаем с редис кэшом. Мы это делаем скорее всего через самый популярный пакет StackExchange

Для инициализации коннекшина мы вызываем такой код:

Это может стать большой проблемой, если коннект был установлен быстро, вы не почуствуете разницу, но если ним были заминки и он может выполняться например около 30 секунд, блокируя наш поток. Для того чтобы так не происходило, необходимо использовать асинхронный код для этого:

ResponseCache Атрибут

Позволяет настроить для метода или класса параметры, необходимые для задания соответствующих заголовков в кэширование ответов (кэшировать или не, если да то на сколько кэшировать и др параметры)

Профили кэша

Вместо дублирования ResponseCache Атрибута, можно использовать кэш профиль, например:

Всегда используйте асинхронное программирование и избегайте блокирующих запросов

При разработке приложений ASP.NET Core старайтесь избегать создания блокирующих запросов. Блокирующий запрос означает запрос, который блокирует следующее выполнение, пока оно не будет завершено. Блокирующий запросили синхронный запросможет быть любым: либо вы извлекаете данные из API, либо выполняете некоторые внутренние операции. Вы должны всегда выполнять запрос в асинхронном режиме.

Создавая ASP.NET Core приложение, вы должны его проектировать таким образом чтобы оно могло обрабатывать множество запросов одновременно. Асинхронные интерфейсы API позволяют использовать небольшой пул потоков для обработки тысяч одновременных запросов, не ожидая (как они это делают в синхронном программировании). Вместо того чтобы ожидать завершения выполнения синхронной задачи выполняющейся длительное время, поток может работать на другой запрос.

Рекомендации:

Х Не используйте:

  • Вызовы методов которые могут бликировать асинхронные вызовы путем выхова Task.Wait или Task.Result.
  • Избегайте блокировок на всех стадиях разработки приложения. ASP.NET Core спроектирован так чтобы выполнять все в асинхронном режиме.

Используйте

  • Сделайте ‘hot code path’ места асинхронными.
  • Делайте запросы к Data access layer’y и долгим API операциям асинхронно.
  • Сделайте методы Контроллера асинхронными. Весь стек вызовов является асинхронным, это позволит вам использовать преимущества async/await шаблонов.

Минимизируйте аллокации больших объектов

Сборщик мусора .NET Core автоматически управляет распределением и освобождением памяти в приложениях ASP.NET Core. Автоматический сбор мусора обычно означает, что разработчикам не нужно беспокоиться о том, как или когда освобождается память. Однако очистка объектов, на которые нет ссылок, занимает процессорное время, поэтому разработчикам следует минимизировать распределение объектов в ‘hot code path’. Сборка мусора особенно дорога для больших объектов (> 85 Кбайт). Большие объекты хранятся в Large object heap объектов, и для их очистки требуется полная сборка мусора (поколение 2). В отличие от коллекций поколения 0 и поколения 1, коллекция поколения 2 требует временной приостановки выполнения приложения. Частое распределение и удаление больших объектов может привести к нестабильной производительности.

Рекомендации:

Х Не Создавайте много больших короткоживущих объектов в ‘hot code path.

Используйте кэширование больших объектов, которые часто используются. Кэширование больших объектов предотвращает дорогие аллокации. Так же можно использовать один из классических паттернов Flyweight для работы с такими объектами.

Используйте ArrayPool для хранения больших массивов.

Использование класса ArrayPool для «аренды» и «возврата» буферов (с использованием методов Rent и Return) может повысить производительность в ситуациях, когда массивы часто создаются и уничтожаются, что приводит к значительному давлению памяти на сборщик мусора.

Оптмизация Data Access Layer’a

Эффективное чтение и запись данных очень важны для хорошей производительности.

Рекомендации:

Используйте асинхронные запросы к Data access layer’y.

Используйте кэширование часто используемых данных, извлеченных из базы данных или удаленного сервиса (если это позволяет бизнес-логика). В зависимости от сценария используйте MemoryCache или DistributedCache. Для дополнительной информации см. раздел «Используйте кэширование».

Минимизируйте количество запросов для получения данных (цель получить данные за один запрос, не делая несколько запросов)

Используйте фильтрацию и агрегирование запросов LINQ (например, с помощью операторов .Where, .Select или .Sum), чтобы фильтрация выполнялась базой данных.

Х Не запрашивайте больше данных, чем неободимо. Ваши запросы должны вернуть только те данные. которые необходимы для текущего HTTP-запроса

Х Избегайте больше N + 1 проблемы


Пул HTTP-подключений с HttpClientFactory

Несмотря на то что HttpClient реализует интерфейс IDisposable, он предназначен для повторного использования. Закрытые экземпляры HttpClient оставляют сокеты открытыми в состоянии TIME_WAIT на короткое время. Если часто используется класс, который создает и удаляет объекты HttpClient, приложение может исчерпать доступные сокеты. HttpClientFactory был введен в ASP.NET Core 2.1 как решение этой проблемы. Он обрабатывает пул HTTP-соединений для оптимизации производительности и надежности.

Стремитесь к быстродействию в коде который вы используете в middleware

Запускайте код который выполняется длительное время за пределами HTTP реквестов

Большинство запросов к приложению ASP.NET Core могут обрабатываться контроллером или моделью страницы, вызывая необходимые сервисы и возвращая HTTP-ответ. Для некоторых запросов, которые включают в себя длительные задачи, лучше сделать весь процесс запрос-ответ асинхронным.

Рекомендации:

Х Избегайте ожидания завершения длительных задач как части обычной обработки HTTP-запроса.
Используйте обработку долго-выполняющихся запросов с помощью фоновых служб (например Azure function, AWS Lambda, и тд). Завершение работы вне процесса особенно полезно для задач с интенсивным использованием процессора.
Используйте тулы такие как SignalR, для асинхронной связи с клиентами в режиме реального времени.

Минифицируйте client assets и используйте сжатие ответов с сервера

Приложения ASP.NET Core интерфейсами часто обслуживают множество файлов JavaScript, CSS или изображений. Производительность при «initial load» может быть улучшена за счет:

  • Bundling и минификация (лучше всего на данный момент использовать WebPack для этих целей).
  • Используйте CDN
  • Ужимайте картинки
  • Используйте Gzip для ответов с сервера

Код который блокирует потоки

Одной из распространенных причин медленной работы кода в некоторых местах является истощение пула потоков — когда ваш пул потоков слишком занят другими задачами и недоступен для перехода и получения новых запросов.
Если наше приложение большое и сложно найти участки кода которые могут на это влиять, найти их нам поможет этот Nuget пакет.

Установим его с Nuget’a

И вызываем метод в нашем IApplicationBuilder

Плюсы/минусы различных настроек кэширования ASP.NET

49 vesuvious [2013-09-22 00:32:00]

Недавно я задал вопрос о кэшировании данных приложения в приложении ASP.NET MVC WebAPI, и это привело меня к новому вопросу. Каковы преимущества/недостатки различных методов кэширования, доступных в ASP.NET?

Использование переменных статического члена:

Я уверен, что есть другие, и я знаю, что все они технически хранят данные в памяти. так что любая идея, что я должен использовать для ASP.NET MVC webapi?

c# caching asp.net asp.net-mvc asp.net-web-api

3 ответа

32 Решение R.C [2013-09-22 07:09:00]

Каждая технология/методы кэширования имеет свой собственный набор функций. Эти функции могут казаться невыгодными в одном приложении, но могут быть полезны в других требованиях к приложениям.

Итак, короче говоря, в зависимости от ваших требований решайте, какая технология кеширования и какие функции лучше всего подходят вам.

For example, Let us discuss some client side Caching techniques .

Илон Маск рекомендует:  Сравнение удобства пользовательских интерфейсов cms на русскоязычном рынке

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

Преимущество этой функции: Снижает рабочую нагрузку на вашем сервере, сохраняя информацию о странице с помощью клиентских опций.

Однако MSDN четко говорит, что: этот подход имеет минимальную поддержку безопасности.

Таким образом, можно или не может использовать эту функцию всегда, так как существуют соображения безопасности.

Consider one more example , Page Output caching : это 2 типа, кэширование вывода страницы и кэширование фрагмента страницы.

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

And one last comment on Application vs HttpRuntime.cache :

Application не является кешем, его глобальной коллекцией значений значений. если вы добавите объект в Application , он останется до тех пор, пока аппроксимация не будет восстановлена.

  • Переменные приложения — это общие переменные среди всех пользователей веб-приложения.
  • Переменные приложения ведут себя как статические переменные, и они заменяют статические переменные, поскольку статические переменные не имеют состояния в веб-приложениях.
  • В переменных приложения должны сохраняться только общие значения, и как только они не используются, они должны быть явно удалены.


Cache : можно добиться значительных улучшений производительности в приложениях ASP.NET путем кэширования часто запрашиваемых объектов и данных в классах Application или Cache . Хотя класс Cache , безусловно, обеспечивает гораздо большую гибкость и контроль, он, по-видимому, предлагает предельное преимущество с точки зрения увеличения пропускной способности по сравнению с классом Application для кэширования. Было бы очень сложно разработать схему тестирования, которая могла бы точно измерить потенциальные преимущества класса Cache встроенного управления менее используемыми объектами через процесс очистки, а не тот факт, что приложение не предлагает эту функцию. Разработчик должен принять решение в этом случае и должен основываться на потребностях и удобстве проекта и его шаблонах использования. Проверьте эту ссылку для более подробной информации.

Обратитесь к этой статье MSDN, чтобы получить полное объяснение по всем технологиям кэширования в Asp.net с обсуждением особенностей каждой технологии.

Кроме того, эти 2 ссылки являются отличным источником для начала:

8 Joe [2013-09-22 15:37:00]

Относительно MemoryCache vs ASP.NET Cache: они обеспечивают очень похожую функциональность. В приложении ASP.NET 4 я обычно предпочитаю кэш ASP.NET, если не по какой-либо другой причине, а затем из-за ошибки в .NET 4, которая по-видимому, зафиксирован в .NET 4.5.

Статические поля подходят для хранения общих данных, для которых не требуется политика истечения срока действия.

Состояние приложения не намного больше, чем статический словарь с семантикой блокировки, совместимый с классическим ASP — я бы использовал его только для обратной совместимости с старым классическим ASP-кодом.

При использовании веб-API ваш первый выбор для кэширования должен всегда состоять в том, чтобы настроить заголовки кеширования в ответе HTTP. HttpResponseMessage.CacheControlHeader .

Ваши последние параметры должны быть любыми, что зависит от HttpContext или HttpRuntime , так как это свяжет вас с конкретными хостами. Приложения Web API должны быть построены независимо от их хоста.

HTTP сессия. Session. Состояние сеанса. Работа с сессиями в ASP.NET MVC

Давайте рассмотрим такое понятие как сессия (HTTP-сессия, Session). Или по-другому, сеанс пользователя. Почему важно понимать механизм работы сессий. И посмотрим, как можно работать с состояниями сеансов на платформе ASP.NET.

Прежде чем мы дадим определение термину «сессия», давайте немного рассмотрим предысторию, зачем вообще возникла потребность в сессиях, рассмотрим одну особенность протокола HTTP.

Одной из основных особенностей протокола HTTP является то, что он не обязывает сервер сохранять информацию о клиенте между запросами, то есть идентифицировать клиента. Это так называемый stateless-протокол. Связь между клиентом и сервером заканчивается как только завершается обработка текущего запроса. Каждый новый запрос к серверу подразумевается как абсолютно уникальный и независимый, даже если он был отправлен повторно от одного и того же источника.

Что, если оставить stateless-природу протокола HTTP и не идентифицировать пользователя? Без состояний сеанса можно легко обойтись, если на вашем сайте представлена статичная (обезличенная) информация, например, новостная статья, состоящая из текста и изображений. В таком контексте совершенно необязательно ассоциировать несколько запросов с одним пользователем. Ведь содержание статьи никак не изменится, будь то десять запросов с одного устройства, либо десять запросов от разных людей с разных устройств.

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

Вот как раз в таких ситуациях, когда требуется персонализировать запросы от одного клиента, мы будем использовать сессии.

Когда клиент впервые передает персональные данные в запросе, на сервере создается новая сессия для этого клиента. В период времени жизни сессии все запросы от этого клиента будут однозначно распознаны и связаны с ним. По истечении этого времени связь с клиентом будет потеряна, и очередной запрос от него будет обрабатываться как абсолютно уникальный, никак не связанный с предыдущими.

Например, при совершении покупки в онлайн магазине персональная информация пользователя сохраняется в сессии, пока он путешествует по сайту. Это выбранные товары в корзине, адрес доставки, контактные данные и так далее.

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

  1. скрытые поля на HTML-форме (hidden form fields)
  2. куки (cookies)
  3. сессия (session, session State)

Попробуем их реализовать, используя платформу ASP.NET. Давайте кратко рассмотрим первые два механизма, и особое внимание уделим третьему, как более надежному, удобному и безопасному.

Скрытые поля на HTML-форме (hidden form fields)

Суть данного подхода состоит в том, что мы обеспечиваем навигацию по сайту при помощи стандартных html-форм. И при каждом следующем запросе мы сохраняем данные из предыдущего в скрытых полях на форме. Например:

В данном примере мы на первой html-форме получаем имя пользователя. Далее в контроллере в методе Forms2() мы извлекаем это значение из коллекции Form и передаем в представление посредством объекта ViewBag. В этом представлении генерируется код новой формы и в скрытом поле сохраняется имя пользователя. Таким образом, значение имени пользователя будет передано уже на третью формы вместе с дополнительной информацией — значением поля с именем «foodName». И так далее.

Давайте рассмотрим особенности такого подхода. Плюсов практически нет, разве что реализовать данную технику можно очень быстро. Но опять же и другие подходы тоже можно реализовать очень быстро. А вот минусы есть, и довольно существенные:

  • Во-первых, этот вариант не будет работать, если html-формы на наших страницах статичны, то есть жестко закодированы. И чтобы это исправить, чтобы повлиять на html-разметку мы прибегаем к помощи какой-нибудь серверной технологии (в данном случае механизм ViewBag);
  • Это безопасность. Хоть вводимые нами данные не передаются через url-параметры в адресной строке и визуально не видны на странице, мы с легкостью можем их получить или подменить или удалить или украсть просто изучив исходный код страницы или структуру запроса;

Куки (cookies)

В данном подходе мы не храним сессионные данные непосредственно на форме, вместо этого используется стандартный механизм работы cookies между клиентом и сервером. В cookies и хранятся все пользовательские данные.

При выборе этого подхода опять же главной остается проблема безопасности наших данных, которые мы передаем на сервер – их легко подменить или украсть, они лежат в открытом виде. Также, если в настройках приватности браузера клиента отключен прием куки с сайтов, то такой вариант ведения сессии вовсе не будет работать.

Серверный механизм управления сессией (Session, SessionState)

Разберем, как работает механизм сессии со стороны сервера и со стороны клиента.

При стандартных настройках работы состояния сеанса для отслеживания серии запросов от одного клиента используется т.н. сессионная куки (session cookie). Алгоритм следующий:

  1. Абсолютно для каждого нового запроса на сервер (неважно, разные это клиенты или один) ASP.NET генерирует уникальный идентификатор сессии.
    Идентификатор сессии представляет собой случайно сгенерированное число, закодированное с помощью специального алгоритма в строку длиной 24 символа. Строка состоит из литералов от A до Z в нижнем регистре, а также чисел от 0 до 5. Пример идентификатора — hjnyuijl1pam3vox2h5i41in
  2. Если в течение текущего запроса данные клиента НЕ сохраняются для дальнейшей работы с ним, то и время жизни сессии этого клиента заканчивается (фактически не начавшись). При этом ранее сгенерированный идентификатор сессии становится недействительным (так как не был использован). В ответ на такой запрос клиент не получает ничего, чтобы связало его с новой сессией.
  3. Если же данные клиента (например, имя, адрес доставки товара) сохраняются на сервере, ASP.NET связывает сохраненные данные с ранее сгенерированным идентификатором сессии. Далее создается специальная сессионная куки, и в нее записывается также этот идентификатор. Эта куки добавляется в ответ на запрос и сохраняется в браузере клиента. Таким образом, создается связь клиента и его персонализированной информации на сервере. Новая сессия для данного клиента создана.
  4. При каждом следующем запросе клиент передает на сервер персональный идентификатор сессии через куки. Сервер сопоставляет идентификаторы и «узнает» клиента в рамках текущей сессии.
  5. До тех пор пока клиент передает свой персональный ключ, сессия считается активной. Сессия может закончиться по разным причинам, например, вручную на стороне сервера или по истечении какого-то установленного времени (таймаут).


От теории перейдем к практике. Давайте запрограммируем данный алгоритм и посмотрим, как он выполняется. Для этого используем специальный класс HttpSessionState . При работе в контроллере можно воспользоваться свойством HttpContext.Session . Работать с сессией очень просто, как с любой NameValueCollection :

В этом участке кода мы записываем в состояние сеанса имя пользователя. Это имя мы забираем с html-формы, которую он нам отправил. Дополнительно через свойства мы узнаем, создана ли эта сессия только что, то есть в рамках текущего запроса (если да, то и значение свойства IsNewSession будет равняться true), и уникальный идентификатор сессии. Этот идентификатор после обработки запроса будет автоматически записан в сессионную куки (если еще нет) и отправлен в ответе клиенту.

В браузере клиента можно наблюдать соответствующую куки и идентификатор его сессии:

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

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

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

Item[index] – возвращает элемент данных по его индексу
Item[key] – возвращает элемент данных по его ключу
Remove(index) – удаляет элемент данных по его индексу
Remove(key) – удаляет элемент данных по его ключу
Clear() – удаляет все данные
Count – возвращает общее количество элементов данных для текущей сессии
Abandon() – принудительно завершить сессию
SessionID — возвращает идентификатор текущей сессии
IsNewSession – возвращает true если сессия была создана в рамках текущего запроса
Timeout – возвращает число минут, допустимое между запросами, перед тем как сессия завершится по причине таймаута (по умолчанию, 20 минут)

Изменить настройки для сессии можно либо программно в коде посредством членов класса HttpSessionState , либо через конфигурацию приложения (файл web.config). Например:

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

Введение в Windows Server AppFabric. Сервис Caching Services

Одно из основополагающих правил построения приложений гласит: разработчики не должны тратить свое время на построение инфраструктуры. Даже не смотря на то, что каждое приложение требует некоторую поддержку в виде сервисов, люди, которые разрабатывают эти приложения должны фокусироваться только на создании значимом для своих пользователей функционале. Какая бы не требовалась инфраструктура, он должна предлагаться платформой, для которой приложение строится.

Принимая это во внимание, одним из способов улучшить платформу является предложение лучшей инфраструктуры приложений на ней. И именно это является целью Windows Server AppFabric. Предлагая набор расширений для Windows Server, Microsoft стремится упростить для разработчиков создание быстрых, более масштабируемых и более управляемых приложений.

Первый выпуск Windows Server AppFabric содержит две части (сегодня доступна версия 1.1 со множеством нововведений. — Прим. пер.):

  • Сервис AppFabric Caching Services, который позволяет ускорить доступ к часто используемым данным приложений
  • Сервис AppFabric Hosting Services, который позволяет упросить запуск и управление сервисами созданными на базе WCF и особенно созданными на базе Windows Workflow Foundation

Windows Server AppFabric предлагает расширения для роли Application Server и эти расширения бесплатны для использования вместе или раздельно. В этом введении рассматриваются обе части AppFabric.

AppFabric Caching Services

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

Но в случае если все эти сервера зависят от одного сервера БД, доступ к данным может быстро стать узким местом вашей архитектуры. Добавление новых серверов не поможет, когда странице ASP.NET придется ожидать необходимые ей данные. Одно из решений запускать сервер БД на более мощной машине. Это может сработать, но и тут существуют ограничения: вам придется масштабироваться заменяя сервер на все более и более мощные машины и такая замена может стать слишком дорогостоящей. Что нам на самом деле нужно, так это способ масштабирования, при котором часто запрашиваемые данные были доступны на нескольких серверах, что позволит нам избежать узкого места в виде одного сервера.

Эффективный способ достижения этого — это создание распределенного кэша, который распространяет данные среди нескольких компьютеров. Вместо того, чтобы отсылать каждый запрос на один сервер БД, приложение ASP.NET сможет получить необходимые данные от одной из соседних машин. Нагрузка будет распределенной и приложение начнет работать быстрее. Это именно тот функционал, который предлагает сервис AppFabric Caching Services.

Как работает AppFabric Caching Services

Основным компонентом сервиса AppFabric Caching Services является клиент кэша, например страница ASP.NET, которая обращается к кластеру кэша содержащего некоторое количество серверов кэша. Каждый сервер кэша запускает экземпляр сервиса AppFabric Caching Services и поддерживает доступ к некоторому набору закэшированных данных. Каждый клиент кэша может так же поддерживать свой локальный кэш данных, используя специальные компоненты поставляемые вместе с AppFabric Caching Services. На рисунке 1 представлена схема всех компонентов:

Рис.1. Схема организации AppFabric Caching Services

Когда клиент кэша впервые получает некий кусок данных, например информацию переданную пользователем в ASP.NET-приложение или значения прочитанные из БД, клиент может сохранить эту информацию с уникальным именем в кластере кэша AppFabric Caching Services (или как будет рассказано далее, приложения ASP.NET могут сохранять информацию прозрачно через объект Session, так что даже не потребуется переписывать код у имеющегося приложения). Для клиента все остальные сервера кэша в кластере выглядят как одно большое хранилище — клиент никогда не знает и ему не нужно знать на каком из физических серверов хранятся его закэшированные данные. По желанию, клиент может сохранять данные и у себя в локальном кэше.

Когда клиенту снова требуется получить доступ к тем же данным, он запрашивает их через указанное уникальное имя. Этот запрос проверяет локальный кэш (если такой есть). Если данные найдены, то клиент использует их из локального кэша. Если данных нет в локальном кэше, запрос отправляется в кластер кэша. Если данные есть в кластере, клиент использует их. Весь этот процесс прозрачен для клиента, он просто отправляет запрос и AppFabric Caching Services берет на себя все остальное. В случае, если данные не были найдены в кластере кэша, клиенту придется запрашивать данные в БД.

Сервис AppFabric Caching Services на этапе разработки носил кодовое имя «Velocity», имя которое точно определяет что этот сервер делает: он позволяет сделать повторяющиеся запросы к данным быстрее. Вместо того чтобы делать множество однотипных запросов к БД, этот сервис позволяет получить данные прямо из локальной или распределенной памяти. Для приложений, которые часто запрашивают одинаковые данные, а таких очень много, кэширование значительно улучшает производительность и масштабируемость.

Сервис AppFabric Caching Services спроектирован для использования с .NET-приложениями, так что кэшируемые данные могут быть сериализованы в объект .NET. Поместив однажды объект в кэш, клиент может затем обновить его или удалить из кэша. Сохраненные в кэше элементы так же могут быть удалены из кэша самим сервисом по причине истечения срока хранения или в связи с необходимостью разместить в кэше более актуальные данные. Данные в локальном кэше могут так же устаревать, кроме того для локальных данных может быть установлена синхронизация с такими же данными из распределенного кэша для внесения изменений и синхронного удаления.

Несколько клиентов кэша могут использовать один и тот же кластер кэша. Это имеет смысл, так как масштабируемое приложения скорее всего будет дублировать свою бизнес-логику на нескольких машинах, каждая из которых требует доступа к кластеру кэша. Однако, доступ нескольких машин к одному и тому же кластеру кэша может привести в проблемам безопасности. Для того, чтобы разделение одного кластера кэша между несколькими клиентами более безопасным, все данные передаваемые между клиентом кэша и кластером могут иметь цифровую подпись либо быть зашифрованными. Кроме того, администратор имеет механизмы позволяющие ограничить список учетных записей, которые имеют доступ к кэшу. Организация должна быть твердо уверена, что все клиенты использующие один кэш являются доверенными, так как потенциально они могут получить доступ к данным друг друга.

Кэширование полезно при работе с разными типами данных. Например, кэширование весьма полезно при работе с неизменяемыми во времени данными, которые запрашиваются разными клиентами (информация о каталоге онлайн-поставщика). Другой хороший пример использования кэширования — это хранение изменяемых данных, которые однако потребляются только одним клиентом, например, информация о сессии ASP.NET. И снова, этот пример описывает случай когда проблемы управления одновременным доступом к кэшированным данным не возникает.

Но что насчет того, когда данные, которые постоянно изменяются должны одновременно потребляться большим числом клиентов? Кэширование может быть использовано и в этом случае, но с одной оговоркой: необходим контроль за одновременным доступом. Для того, чтобы адресовать эту проблему сервис AppFabric Caching Services поддерживает оба оптимистичный контроль одновременного доступа основанный на назначении номера версии и пессимистичный контроль одновременного доступа использующий явные блокировки.

Сценарий: использование кэширования в приложении ASP.NET

Приложения ASP.NET являются наиболее важными клиентами для сервиса AppFabric Caching Services. Как было сказано ранее, данные хранимые в объекте сессии ASP.NET самый очевидный кандидат для кэширования. На самом деле сервис предлагает встроенную поддержку для этого — разработчику необходимо только задать опции конфигурации и объект сессии будет прозрачно сохраняться в кластере кэша. Обратите внимание: это означает, что разработчики ASP.NET могут получить преимущества распределенного кэширования без модификации кода их приложения. Это позволяет использовать несколько копий веб-серверов с запущенными экземплярами приложения ASP.NET без использования SQL Server для хранения данных сессии. На рисунке 2 показано как этот механизм работает:

Рис.2. Схема работы ASP.NET-приложения с AppFabric Caching Services

Этот простой сценарий начинается с того, что пользователь отправляет некоторую информацию, которую ASP.NET сохраняет в пользовательский объект сессии (шаг 1). Веб-сервер, который обрабатывает запрос, сконфигурирован так, чтобы кэшировать объекты сессии в кластере AppFabric Caching Services и поэтому пользовательские данные записываются в один или более серверов кэша (шаг 2). Следующий запрос от пользователя основывается на данных, сохраненных на шаге 1, но этот запрос обрабатывается уже другим сервером (шаг 3). Код ASP.NET на этом сервере обращается к тому же объекту сессии, что на деле означает прозрачный доступ к кластеру кэша для доступа к данным (шаг 4). Это позволяет информации полученной на шаге 1 быть доступной для приложения. Обратите внимание, что нам не пришлось оперировать с БД для хранения информации, а так же нам не требуется чтобы запросы пользователя обрабатывал один и тот же сервер. Результат работы этой инфраструктуры — повышенная производительность и улучшенная масштабируемость ASP.NET-приложения.

Сценарий: использование механизма высокой доступности

Сервис AppFabric Caching Services сохраняет все данные в памяти — они не записываются на диск. По умолчанию, каждый кэшируемый объект хранится только на одной машине в кластере кэша. Для того, чтобы увеличить надежность, в случаях когда сервер становится недоступным, AppFabric Caching Services предлагает поддержку механизма высокой доступности. Этот механизм позволяет создавать дублируемые копии кэшированных данных на других машинах в кластере кэша. Если сервер кэша, который хранит первичную копию данных, становится недоступным, то данные будут получены из вторичного хранилища. Рисунок 3 демонстрирует всю идею:

Рис.3. Высокая доступность AppFabric Caching Services


В этом примере, механизм высокой доступности выключен, так что каждый элемент кэшируемых данных сохраняется в двух разных серверах кэша. Первичная копия, показанная на рисунке в виде залитой фигуры, принимает все изменения с данными. Эти изменения автоматически реплицируются на вторичную копию, представленную в виде пустой фигуры. Здесь, сервер кэша содержащий первичную копию данных X становится недоступным (запланированно или случайно, шаг 1). Когда клиент кэша запрашивает данные X (шаг 2) кластер кэша скрытно перенаправляет запрос к вторичной копии и возвращает значение (шаг 3).

Этот пример показывает чтение данных, но и запрос на обновление будет точно так же обработано, когда сервер кэша с первичными данными будет недоступным. Как только AppFabric Caching Services определяет, что сервер с первичными данными недоступен, существующий сервер со вторичными данными становится первичным плюс создается новая вторичная копия на одном из доступных серверов. Все это прозрачно для клиента, просто работает так как будто с серверами ничего не происходило.

Независимо от того используется или нет механизм высокой доступности, сервис AppFabric Caching Services позволяет ускорить доступ к часто запрашиваемым данным. Это очень полезный функционал расширяющий имеющую инфраструктуру Windows Server.

Предложения для улучшенной поддержки бизнес-логики так же полезны и о том, что Windows Server AppFabric может предложить в этом плане рассказывается в следующей части.

Изучение кэширования в ASP.NET

Written on 24 Января 2014 . Posted in ASP.NET

ОГЛАВЛЕНИЕ

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

Введение

Большее число клиентов означает большее число запросов к веб-серверу и тяжелую нагрузку на сеть, вызывающую падение производительности. Для решения этой проблемы было применено кэширование в веб-приложении. Большинство описанных в статье вещей известно многим читателям, но статья была написана так, чтобы новички тоже поняли ее. В ходе написания статьи была обнаружена такая интересная особенность, как установка разных мест для кэширования. Также была приведена соответствующая диаграмма Visio.

Что такое кэширование?

К веб-приложениям обращается множество пользователей. На веб-сайт ложится тяжелая нагрузка, которая может расти экспоненциально и тормозить сервер и доступ к сайту. Медленный доступ – самая распространенная проблема веб-сайтов при одновременном обращении к ним большого числа клиентов. Для решения этой проблемы можно использовать высокий уровень аппаратной конфигурации, балансировщик нагрузки, широкую полосу пропускания. Однако нагрузка – не единственная причина, тормозящая веб-сайт, поэтому надо создать какой-то механизм, обеспечивающий быстрый доступ к данным и прирост производительности. Кэширование дает такое решение.

Кэширование – это метод, позволяющий хранить часто используемые данные, и таким образом веб-страницы могут временно храниться на локальном жестком диске для дальнейшего извлечения. Этот метод сокращает время доступа, когда много пользователей одновременно обращаются к веб-сайту, или когда один пользователь многократно обращается к веб-сайту. Кэширование для веб-приложений может происходить на клиенте (кэширование в браузере), на сервере между клиентом и веб-сервером (кэширование в прокси / кэширование в обратном прокси) и на самом веб-сервере (кэширование страницы или кэширование данных).

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

Разные места кэширования

Кэширование в веб-приложении можно делать на стороне клиента (браузер клиента), между клиентом и сервером (кэширование в прокси и в обратном прокси), или на стороне сервера (кэширование данных/кэширование вывода страницы). Места кэширования классифицируются следующим образом:
1. Кэширование на клиенте
2. Кэширование в прокси
3. Кэширование в обратном прокси
4. Кэширование на веб-сервере

При кэшировании на клиенте браузер клиента осуществляет кэширование путем хранения кэшированных данных на локальном диске в виде временного файла или во внутренней памяти браузера. Это обеспечивает быстрый доступ к некоторой информации, что уменьшает нагрузку на сеть и на сервер. Эту информацию нельзя разделить с другими клиентами, поэтому она специфична для клиента.

Рис. 1 : Кэширование на клиенте

Плюсы
1. Легкий доступ к данным, кэшированным на локальном клиенте
2. Уменьшает сетевой трафик

Минусы
1. Кэшированные данные полностью зависят от браузера, поэтому они не разделяемы
2. Кэширование в прокси: Основной недостаток кэширования на клиенте заключается в том, что данные, хранящиеся в браузере клиента, являются специфичными для клиента. Кэширование в прокси использует выделенный сервер, хранящий кэшированную информацию между клиентом и веб-сервером в разделяемом месте, так что все клиенты могут использовать одни и те же разделяемые данные. Прокси-сервер (например, прокси-сервер Microsoft) исполняет все запросы к веб-странице без отправки запроса к фактическому веб-серверу через интернет, обеспечивая более быстрый доступ.

Рис. 2: Кэширование в прокси

Кэширующие прокси часто помещаются вблизи сетевых шлюзов для уменьшения трафика. Иногда несколько кэширующих прокси-серверов используются для большего числа клиентов. Это называется кэширующим массивом.

Рис. 3: Кэширующий массив

Плюсы
1. Легкий доступ к данным, кэшированным на прокси-сервере
2. Уменьшает сетевой трафик

Минусы
1. Требует развертывания и издержки инфраструктуры для обслуживания кэширующего прокси-сервера
2. Кэширование в обратном прокси: Можно поместить прокси-сервер перед веб-сервером, чтобы уменьшить количество получаемых им запросов. Это позволяет прокси-серверу отвечать на часто получаемые запросы и передавать веб-серверу только остальные запросы. Это называется обратным прокси.

Рис. 4: Кэширование в обратном прокси

Плюсы
1. Легкий доступ к данным, кэшированным на обратном прокси-сервере
2. Уменьшает количество запросов

Минусы
1. Так как сервер конфигурируется перед веб-сервером, может увеличиться сетевой трафик
2. Кэширование на веб-сервере: При кэшировании на веб-сервере кэшированные данные хранятся внутри веб-сервера. Кэширование данных и кэширование страницы использует механизм кэширования веб-сервера.

Рис. 5: Кэширование на веб-сервере

Плюсы
1. Повышает производительность сайтов путем уменьшения извлечения данных в обе стороны из базы данных или какого-то другого сервера

Минусы
1. Увеличивает нагрузку на сеть

Преимущества кэширования
1. Уменьшает нагрузку на сервер
2. Уменьшает потребление полосы пропускания

Возможность кэширования в ASP.NET

ASP.NET поддерживает кэширование страницы, неполной страницы (фрагмента) и кэширование данных. Кэширование динамически генерируемой страницы называется кэшированием вывода страницы. При кэшировании страницы, когда кэшируется динамически генерируемая страница, к ней обращаются только в первый раз. Любое последующее обращение к той же самой странице будет возвращаться из кэша. ASP.NET также позволяет кэшировать часть страницы, что называется кэшированием неполной страницы или кэшированием фрагмента. Кэшируются другие данные сервера (например, данные сервера SQL, данные XML), к которым можно легко обратиться без повторного извлечения данных с помощью кэширования данных. Кэширование уменьшает число запросов «туда-обратно» к базе данных и другим источникам данных. ASP.NET предоставляет полноценный механизм кэширования данных, снабженный поддержкой уборки мусора (на базе приоритета кэша), истечения, зависимостей от файла, ключа и времени. Есть два места, где кэширование может использоваться для повышения производительности приложений ASP.NET.

Рис 6: Возможность кэширования в ASP.NET


На рисунке выше (1) используется для возвратного кэширования страницы, то есть он используется в кэшировании вывода, и (2) избавляет от передачи данных туда-обратно путем хранения данных с помощью кэширования данных.

ASP.NET поддерживает два типа политик истечения, определяющих, когда объект истекает или удаляется из кэша.

Абсолютное истечение: Определяет, что истечения происходят в указанное время. Абсолютные истечения задаются в формате полного времени (чч:мм:сс). Объект будет удален из кэша в указанное время.

Разные типы кэширования

ASP.NET поддерживает три типа кэширования:
1. Кэширование вывода страницы [кэширование вывода]
2. Кэширование фрагмента [кэширование вывода]
3. Кэширование данных

Кэширование вывода страницы

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

Рис. 7: Процесс выполнения страницы ASP.NET

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

Рис. 8: Кэширование вывода страницы

На рисунке при генерации первого запроса кэшируется страница, и для дальнейших запросов той же страницы страница извлекается из кэша вместо повторной генерации страницы.

Для кэширования вывода директива OutputCache добавляется на любую страницу ASP.NET с заданием длительности (в секундах) кэширования страницы.

Пример

Также можно установить свойство кэширования из отделенного кода:

Надо указать длительность и атрибут VaryByParam. Длительность определяет, как долго кэш будет сохраняться. VaryByParam определяет, меняется ли кэш со значениями параметра.

Рис. 9: Кэширование нескольких страниц на базе параметров

Как показано на рисунке выше, если для страницы используется строка запроса, и надо кэшировать все страницы на базе строки запроса, то придется использовать атрибут VaryByParam кэширования вывода. На базе строки запроса данные должны кэшироваться, и когда пользователь запрашивает страницу со строкой запроса (ID на рисунке), страница извлекается из кэша. Следующий пример описывает использование атрибутов VaryByParam.

Пример:

Следующая таблица показывает самые распространенные и самые важные атрибуты кэша вывода:

Как хранить (кэшировать?) Данные между несколькими сессиями в ASP.NET

Я пишу приложение веб-формы C # ASP.NET. Короче говоря, это приложение извлекает данные с сервера и отображает их для пользователей.

Чтобы получить доступ к этому серверу, мое приложение должно сгенерировать информацию для входа. Создание информации для входа занимает несколько минут. Эта информация для входа в систему меняется ежедневно, но она одинакова для всех, кто использует мое приложение (в определенный день).

Мое приложение будет ежедневно использоваться сотнями людей. Глупо заставлять каждого пользователя ждать несколько минут для получения информации для входа в систему.

В идеале я хотел бы собирать информацию для входа один раз в день и сохранять результаты где-нибудь на моем сервере.

Какие-нибудь советы? Я знаю, что в .NET есть Cache и Session , но они хранят данные только для одного отдельного пользователя. Есть ли у вас какие-либо методы для хранения этой информации для входа в систему, чтобы я мог получить ее из своего кода?

1 ответ

Вы не правы, кеш работает на уровне приложения, а не на уровне пользователя, от MSDN

Приложение может часто повышать производительность, сохраняя данные в памяти, к которой часто обращаются, и для создания которой требуется значительное время обработки. Например, если ваше приложение обрабатывает большие объемы данных, используя сложную логику, а затем возвращает данные в виде отчета, к которому часто обращаются пользователи, эффективно избегать повторного создания отчета каждый раз, когда пользователь запрашивает его. Точно так же, если ваше приложение содержит страницу, которая обрабатывает сложные данные, но обновляется редко, для сервера неэффективно пересоздавать эту страницу при каждом запросе.

Чтобы помочь вам повысить производительность приложений в этих ситуациях, ASP.NET обеспечивает кэширование с использованием двух основных механизмов кэширования. Первый — это кэширование приложения, которое позволяет вам кэшировать сгенерированные вами данные, такие как объект DataSet или бизнес-объект настраиваемого отчета. Второй — кэширование вывода страницы, которое сохраняет результаты обработки страницы и повторно использует выходные данные вместо повторной обработки страницы, когда пользователь снова запрашивает страницу.

Я думаю, что Application cache подходит лучше, чем другой

О Expire

Есть два способа управления им, вы можете установить X минут как предел, а затем установить, если хотите:

Абсолют : истечение срока действия данных через X минут с момента создания объекта

Абсолютное истечение срока действия: в этом примере данные в кеше будут кэшироваться в течение одной минуты, после чего срок действия кэша истечет. Обратите внимание, что абсолютное истечение и скользящее истечение (ниже) не могут использоваться вместе.

Скольжение : срок действия данных истекает через X минут с момента последнего использования объекта кэша.

Срок действия слайда: в этом примере будут кешироваться некоторые часто используемые данные. Данные будут оставаться в кэше до тех пор, пока не пройдет одна минута, и на них ничего не будет ссылаться. Обратите внимание, что скользящее истечение и абсолютное истечение не могут использоваться вместе.

Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL