Привет, читатель блога 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 должны повиноваться все участники цепочки обмена данными между конечным сервером и клиентом.

[php] Cache-control: no-cache [/php]

Для управления кэшированием 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 вы сможете найти ниже.

[php]

Cache-Control   = «Cache-Control» «:» 1#cache-directive

 

cache-directive = cache-request-directive

| cache-response-directive

cache-request-directive =

«no-cache» [ "=" <"> 1#field-name <"> ]

| «no-store»

| «max-age» «=» delta-seconds

| «max-stale» [ "=" delta-seconds ]

| «min-fresh» «=» delta-seconds

| «only-if-cached»

| cache-extension

 

cache-response-directive =

«public»

| «private» [ "=" <"> 1#field-name <"> ]

| «no-cache» [ "=" <"> 1#field-name <"> ]

| «no-store»

| «no-transform»

| «must-revalidate»

| «proxy-revalidate»

| «max-age» «=» delta-seconds

| cache-extension

 

cache-extension = token [ "=" ( token | quoted-string ) ]

[/php]

 

Мы рассмотрели механизмы управления кэшированием в 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 считается более надежным, так как позволяет избегать временных парадоксов, но в то же время, такой подход более сложный и затратный.

Возможно, эти записи вам покажутся интересными


Выберете удобный для себя способ, чтобы оставить комментарий

This article has 3 comments

  1. Pingback: Ногомяч

    • Кирилл Reply

      Привет!

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

  2. Pingback: Костя

Добавить комментарий для Кирилл Отменить ответ

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

Loading Disqus Comments ...