Тема 6: HTTP объекты. HTTP entity
Привет, читатель блога ZametkiNaPolyah.ru! Продолжим знакомиться с протоколом HTTP в рубрике серверы и протоколы и ее разделе…
Привет, читатель блога ZametkiNaPolyah.ru! Продолжим знакомиться с протоколом 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 сервера, а с ближайшего сервера, у которого в кэше есть информация о том, что содержится в URI (URI в HTTP), который был указан в HTTP запросе, поэтому должны выполняться следующие правила:
Если все эти правила будут соблюдены, можно спокойно утверждать о том, что клиент получит самую достоверную и новую информацию от транзитного сервера, при этом, не обращаясь к конечному.
Предупреждения при кэшировании отправляет сервер в поле заголовка Warning HTTP ответа в том случае, когда информация из кэша теряет свою актуальность. При этом клиент, получив такое HTTP сообщение может обратиться не к кэшу транзитного сервера, а к первоначальному серверу или предпринять какие-либо другие действия.
В версии протокола HTTP 1.1 в качестве механизмов управления кэшированием используется поле заголовка Cache-Control. Заголовок Cache-Control позволяет управлять HTTP кэшем, как клиенту, так и HTTP серверу при помощи директив, которые они передают вместе с ответами и запросами. При этом директивы, передаваемые в поле заголовка Cache-Control, отменяют значения по умолчанию для кэширования в HTTP. Необходимо отметить тот момент, что директивам заголовка Cache-Control должны повиноваться все участники цепочки обмена данными между конечным сервером и клиентом.
[php] Cache-control: no-cache [/php]
Для управления кэшированием HTTP клиенты могут использовать директивы, которые указаны в таблице ниже. Директивы поля заголовка Cache-Control для клиента
Номер | Директивы поля заголовка Cache— Control для клиента и их описание |
1 | Директива поля заголовка Cache— Control для клиентского запроса: no— cache Директива no-cache говорит серверу о том, что для последующего запроса ответ не должен отправляться из кэша без проверки с содержимым исходного сервера. |
2 | Директива поля заголовка Cache— Control для клиентского запроса: no— store Директива no-store говорит серверу о том, что ни запрос клиента, ни ответ сервера не должны кэшироваться. Это сделано для безопасности. |
3 | Директива поля заголовка Cache— Control для клиентского запроса: max— age = seconds Директива max-age говорит серверу о том, что кэш должен быть не старше времени, которое указано в секундах. |
4 | Директива поля заголовка Cache— Control для клиентского запроса: max— stale [ = seconds ] Директива max-stale говорит серверу о том, что клиент примет кэшированный HTTP ответ в том случае, если его возраст не превышает времени, указанного в секундах. |
5 | Директива поля заголовка Cache— Control для клиентского запроса: min— fresh = seconds Директива min-fresh говорит серверу о том, что клиент примет кэшированный HTTP ответ в том случае, если время жизни кэша не больше указанных секунд. |
6 | Директива поля заголовка Cache— Control для клиентского запроса: no— transform Директива min-fresh говорит серверу о том, что к запрашиваемому ресурсу не должно применяться никаких преобразований. |
7 | Директива поля заголовка Cache— Control для клиентского запроса: only— if— cached Директива min-fresh говорит серверу о том, что клиент примет только кэшированный HTTP ответ, если подходящего ответа нет в кэше сервера, то делать ничего не надо. |
Мы рассмотрели механизм управления кэшированием HTTP клиентом, теперь давайте разберемся с механизмами управления кэшированием со стороны HTTP сервера. Другими словами: как HTTP ответы могут управлять кэшированием. Управление кэширование со стороны сервера происходит аналогичным образом – при помощи заголовка Cache-Control, но директивы заголовка Cache-Control у сервера свои и, соответственно, свои механизмы управления кэшированием при HTTP соединение. Давайте сведем серверные директивы заголовка Cache-Control в одну таблицу.
Номер | Директивы поля заголовка Cache— Control для сервера и их описание |
1 | Директива поля заголовка Cache— Control ответа сервера: public Директива ответа сервера Public говорит о том, что ответ сервера можно сохранять в любом кэше. |
2 | Директива поля заголовка Cache— Control ответа сервера: private Директива ответа сервера private говорит о том, что ответ сервера нужно сохранять в закрытом кэше, который предназначен только для этого пользователя. |
3 | Директива поля заголовка Cache— Control ответа сервера: no— cache Директива ответа сервера no— cache говорит о том, что кэшированный ответ не должен отправляться клиенту без его предварительной проверки. |
4 | Директива поля заголовка Cache— Control ответа сервера: no— store Директива ответа сервера no— store говорит о том, что ответ сервера нельзя сохранять в кэше. |
5 | Директива поля заголовка Cache— Control ответа сервера: no— transform Директива ответа сервера no— transform говорит о том, что к ответу сервера не должно применяться никаких преобразований ни одним из узлов цепочки. |
6 | Директива поля заголовка Cache— Control ответа сервера: must— revalidate Директива ответа сервера must— revalidate говорит о том, что если HTTP сообщение сервера устарело, то к нему должна применяться предварительная проверка. |
7 | Директива поля заголовка Cache— Control ответа сервера: proxy— revalidate Директива ответа сервера proxy— revalidate говорит о том, что и предыдущая директива, но только для промежуточных серверов. |
8 | Директива поля заголовка Cache— Control ответа сервера: max— age = seconds Директива ответа сервера max— age говорит о том, сколько живет кэш на сервере. |
9 | Директива поля заголовка Cache— Control ответа сервера: s— maxage = seconds Директива ответа сервера s— maxage говорит о том, что и директива 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 ответы от промежуточных узлов. Выше мы рассматривали директивы поля Cache-Control, не трудно догадаться, какие из директив лежат в основе модели устаревания 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 считается более надежным, так как позволяет избегать временных парадоксов, но в то же время, такой подход более сложный и затратный.
Pingback: Ногомяч
Привет!
Да ты все правильно понял из всех перечисленных тобой узлов может быть получен кэш ресурса или страницы, но ты еще можешь управлять кэшированием при помощи заголовка Cache-Control
Pingback: Костя