Кеширование с ETag в ASP.NET Core

ETag или entity tag - один из механизмов кэширования в HTTP. Фактически сервер присваивает идентификатор состоянию ресурса. Если состояние изменилось идентификатор должен быть обновлен. Это может быть как статика (CSS, картинки, возможно какие то актуальные документы и пр) так и динамически формирующиеся данные.
В общем виде для создания ETag можно использовать хэш-функцию по содержимому ресурса, желательно устойчивую к коллизиям.

Сильные и слабые проверки

Слабая проверка отличается наличием начального W/ в ETag и проверяет, что два ресурса семантически эквивалентны и фактически являются взаимозаменяемыми, хотя могут быть не идентичны байт за байтом.
Сильная проверка ETag проверяет, что содержание в обоих ресурсах байт за байтом идентично, и что все другие поля (такие как Content-Language), также не отличаются. 
Сильные ETags допускают кэширование и сборку частичных ответов, как при запросах диапазона байт.

Вариант использование

Веб-сервер в заголовки HTTP возвращает ETag: 
ETag: "tert34erct3535c"

Клиент может затем кэшировать ресурс вместе с его ETag. Если клиент хочет получить страницу с того же адреса, он пошлет её ранее сохраненную копию ETag вместе с запросом в If-None-Match:
If-None-Match: "tert34erct3535c"

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

  • Это позволяет кэшу быть более эффективным и экономит пропускную способность, так как веб-серверу не нужно отправлять полный ответ, если содержимое не изменилось. 
  • Если ресурс кэшируется на сервере в in-memory хранилище(Redis, Memcache) или хранится в структурном виде (Mongodb или пр) и актуализируется из OLTP по какому то событию, то можно хранится etag вместе с такими данными. Тогда не нужно формировать/выгружать данные, делать хэш и сравнивать с etag, а достаточно только проверить если такой идентификатор в хранилище.
  • Фронтэнду которому регулярно необходимо обновлять представления, может проверять наличие изменений в данных на сервере и обновлять только в случае изменений. Хотя тут конечно есть решения более эффективные. 

Реализация в виде middleware для asp.net core


Комментарии

Популярные сообщения из этого блога

Асинхронное выполнение процедур или триггера в MS SQL Server

Рекурсивные SQL запросы

Кратко про SQLAlchemy Core