Тема 13: Кэширование в HTTP: механизмы клиентского и серверного кэша в HTTP

Привет, читатель блога ZametkiNaPolyah.ru! Продолжим знакомиться с протоколом HTTP в рубрике Серверы и протоколы и ее разделе HTTP протокол.  Эта запись будет о кэширование в HTTP протоколе.  Мы с тобой поговорим о том для чего вообще нужно кэширование в HTTP, о правилах кэширования, о том, какие могут быть ошибки при кэшировании, а так же о том какие есть механизмы о клиента и сервера для управления процессом кэширования в HTTP и о различных моделях при кэширование.

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

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


Для чего нужно кэширование в HTTP протоколе

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

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

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

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

Правильность кэширования в HTTP

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

  1. Проверка достоверности. Сервер, который дает ответ на запрос должен всегда быть в курсе о содержимом конечного сервера, к которому идет обращение.
  2. Новизна кэша. Новизна кэша определяется конечным сервером.
  3. Предупреждение. Транзитный сервер должен предупреждать клиента о том, что его информация из кэша не самая «свежая».

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

Предупреждения при кэшировании в HTTP

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

Механизмы управления кэшированием в HTTP. Поле заголовка Cache-Control в HTTP

В версии протокола HTTP 1.1 в качестве механизмов управления кэшированием используется поле заголовка Cache-Control. Заголовок Cache-Control позволяет управлять HTTP кэшем, как клиенту, так и HTTP серверу при помощи директив, которые они передают вместе с ответами и запросами. При этом директивы, передаваемые в поле заголовка Cache-Control, отменяют значения по умолчанию для кэширования в HTTP. Необходимо отметить тот момент, что директивам заголовка Cache-Control должны повиноваться все участники цепочки обмена данными между конечным сервером и клиентом.

Для управления кэшированием HTTP клиенты могут использовать директивы, которые указаны в таблице ниже. Директивы поля заголовка Cache-Control для клиента

Номер Директивы поля заголовка CacheControl для клиента и их описание
1 Директива поля заголовка CacheControl для клиентского запроса: nocache

Директива no-cache говорит серверу о том, что для последующего запроса ответ не должен отправляться из кэша без проверки с содержимым исходного сервера.
2 Директива поля заголовка CacheControl для клиентского запроса: nostore

Директива no-store говорит серверу о том, что ни запрос клиента, ни ответ сервера не должны кэшироваться. Это сделано для безопасности.
3 Директива поля заголовка CacheControl для клиентского запроса: maxage = seconds

Директива max-age говорит серверу о том, что кэш должен быть не старше времени, которое указано в секундах.
4 Директива поля заголовка CacheControl для клиентского запроса: maxstale [ = seconds ]

Директива max-stale говорит серверу о том, что клиент примет кэшированный HTTP ответ в том случае, если его возраст не превышает времени, указанного в секундах.
5 Директива поля заголовка CacheControl для клиентского запроса: minfresh = seconds

Директива min-fresh говорит серверу о том, что клиент примет кэшированный HTTP ответ в том случае, если время жизни кэша не больше указанных секунд.
6 Директива поля заголовка CacheControl для клиентского запроса: notransform

Директива min-fresh говорит серверу о том, что к запрашиваемому ресурсу не должно применяться никаких преобразований.
7 Директива поля заголовка CacheControl для клиентского запроса: onlyifcached
Директива min-fresh говорит серверу о том, что клиент примет только кэшированный HTTP ответ, если подходящего ответа нет в кэше сервера, то делать ничего не надо.

Мы рассмотрели механизм управления кэшированием HTTP клиентом, теперь давайте разберемся с механизмами управления кэшированием со стороны HTTP сервера. Другими словами: как HTTP ответы могут управлять кэшированием. Управление кэширование со стороны сервера происходит аналогичным образом – при помощи заголовка Cache-Control, но директивы заголовка Cache-Control у сервера свои и, соответственно, свои механизмы управления кэшированием при HTTP соединение. Давайте сведем серверные директивы заголовка Cache-Control в одну таблицу.

Номер Директивы поля заголовка CacheControl для сервера и их описание
1 Директива поля заголовка CacheControl ответа сервера: public

Директива ответа сервера Public говорит о том, что ответ сервера можно сохранять в любом кэше.
2 Директива поля заголовка CacheControl ответа сервера: private

Директива ответа сервера private говорит о том, что ответ сервера нужно сохранять в закрытом кэше, который предназначен только для этого пользователя.
3 Директива поля заголовка CacheControl ответа сервера: nocache

Директива ответа сервера nocache говорит о том, что кэшированный ответ не должен отправляться клиенту без его предварительной проверки.
4 Директива поля заголовка CacheControl ответа сервера: nostore

Директива ответа сервера nostore говорит о том, что ответ сервера нельзя сохранять в кэше.
5 Директива поля заголовка CacheControl ответа сервера: notransform

Директива ответа сервера notransform говорит о том, что к ответу сервера не должно применяться никаких преобразований ни одним из узлов цепочки.
6 Директива поля заголовка CacheControl ответа сервера: mustrevalidate

Директива ответа сервера mustrevalidate говорит о том, что если HTTP сообщение сервера устарело, то к нему должна применяться предварительная проверка.
7 Директива поля заголовка CacheControl ответа сервера: proxyrevalidate

Директива ответа сервера proxyrevalidate говорит о том, что и предыдущая директива, но только для промежуточных серверов.
8 Директива поля заголовка CacheControl ответа сервера: maxage = seconds

Директива ответа сервера maxage говорит о том, сколько живет кэш на сервере.
9 Директива поля заголовка CacheControl ответа сервера: smaxage = seconds

Директива ответа сервера smaxage говорит о том, что и директива max-age, но для CDN-серверов

 

Общий синтаксис механизмов кэширования в HTTP вы сможете найти ниже.

 

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

Модель устаревания кэша в HTTP

Модель устаревания HTTP кэша была разработана для того, чтобы клиенты не делали постоянные запросы к изначальному серверу, а получали актуальные HTTP ответы от промежуточных узлов. Выше мы рассматривали директивы поля Cache-Control, не трудно догадаться, какие из директив лежат в основе модели устаревания HTTP кэша.

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

Модель сравнения кэша в HTTP

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

Например, клиент делает повторный запрос к HTTP серверу к тому же самому URI, при этом контент по данному URI никак не изменился, сервер проанализировал всю эту информацию и вместо того, чтобы отправлять ответ с телом сообщения (HTTP объектом), в котором может быть огромный HTML документ с таблицами стилей и скриптами, сервер просто дает ответ с кодом состояния 304 (Not Modified), после чего браузер подтягивает страничку из кэша, а конечный пользователь думает, что ему эта страница загрузилась с сервера из Австралии.

Помимо условных запросов для модели сравнения HTTP кэша используется поле заголовка Last-Modified, этот заголовок используется сервером и в него записывается дата последнего изменения документа (дата и время в HTTP) и если дата последнего известного изменения совпадает с той датой, что указана в заголовке Last-Modified, то контент, запрашиваемый пользователем, отдается из кэша, если эта дата не совпадает, то ответ дается новый, при этом происходит кэширование и перезапись поля заголовка Last-Modified.

Помимо всего прочего, модель сравнения кэша в HTTP может использовать для проверки актуальности кэша тэг HTTP объекта, который записывается в поле заголовка ETag и который уникален для каждого объекта. Например, в нашем HTML документе был текст Hello, world!!!, а мы его изменили на Hello, World…, так вот значение поля ETag для таких страниц будет разным. Такой подход сравнения кэша в HTTP считается более надежным, так как позволяет избегать временных парадоксов, но в то же время, такой подход более сложный и затратный.

Рекомендую посмотреть и почитать:

3 комментария на «“Тема 13: Кэширование в HTTP: механизмы клиентского и серверного кэша в HTTP”»

  1. Ногомяч:

    Я правильно понял, что кэш ресурса может браться не только из браузера или сервера, на котором болтается сайт, но и с промежуточных серверов, которые ты называешь прокси? И почему прокси?

    • Кирилл:

      Привет!

      Да ты все правильно понял из всех перечисленных тобой узлов может быть получен кэш ресурса или страницы, но ты еще можешь управлять кэшированием при помощи заголовка Cache-Control

  2. Костя:

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

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *