Тема 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

Ногомяч

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

Кирилл

Привет!

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

Костя

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

Текст комментария: