| настройка директив кеширование HTTP-сервера и сессий PHPВводная
Правильно работающий кеш сокращает время открытия странички, существенно уменьшает нагрузку на сервер
и позволяет эффективно применять акселераторы (тот же nginx).
С точки зрения клиента и оператора связи это обсуждалось в статьях об
управлении трафиком и
принудительном кешировании.
Но для того чтобы это работало "из коробки", необходимо правильно настроить web-сервер.
 Cache control
Полное описание лучше почитать в стандарте 
RFC-2616 section 14
 
также рекомендуется к прочтению инструкция от google
Understanding HTTP cache control Server-side cache control headers
Cache-Control:
Pragma:
ETag:
Date:
Expires:
Last-Modified:
 Client-side cache control headers
If-None-Match:
 
Если объект отсутствует в кеше клиента или промежуточном кеше запрос передается серверу и
сервер отдает весь объем данных целиком. Вместе с данными в заголовках передается информация о дате
создания и последнего изменения, правила кеширования и для кешируемых объектов - хеш объекта ETag и 
допустимое время его жизни в кеше. Если правила кеширования допускают, объект также сохраняется в кеше
вместе со значением ETag.
 
Если объект есть в кеше и время валидации еще не подошло, данные отдаются прямо из кеша.
 
Если объект есть в кеше, но пришло время валидации, на срвер передается запрос с заголовком If-None-Match,
содержащим один или несколько ранее переданых в ETag хешей объекта.
Если хеш и соответствующие данные не поменялись, сервер должен вернуть HTTP/1.1 304 Not Modified.
 Store rules
Static public -
статический общедоступный объект, изменения не предвидятся. Как правило это картинки оформления,
библиотечные java-скрипты и т.п.
 
Cache-Control: public, store, cache, no-validate
Etag: <hash>
 
Static private -
объект, видимость или содержимое которого зависит от авторизации
 
Cache-Control: private, store, cache, no-validate
Etag: <hash>
 
Regular object -
периодически меняющийся объект, допустимо считать, что не чаще чем раз в time to live секунд и
логика приложения допускает временное использование устаревших данных.
 
Cache-Control: public/private, store, cache, max-age=<time to live<, must-revalidate
Etag: <hash>
 
Dynamic object -
часто меняющийся объект или же логика приложения требует всегда самые свежие данные
 
Cache-Control: private, max-age=0, must-revalidate
Etag: <hash>
Last-Modified: <some date>
 
Non-cacheable object -
постоянно меняющийся объект, можно cчитать, что содержимое всегда разное
 
Cache-Control: private, no-store, no-cache, max-age=0, must-revalidate
Pragma: no-cache
Expires: Mon, 26 Jul 1997 05:00:00 GMT
Last-Modified: <now>
 
  Cache-Control: public - можно кешировать как на стороне клиента, так и на промежуточных (прокси) серверах
  Cache-Control: private - можно кешировать только на стороне клиента, на промежуточных (прокси) серверах
  кеширование запрещено, т.к. данные зависят от механизма авторизации.
  Cache-Control: cache - можно использовать кешированую копию
  Cache-Control: no-cache - запретить кеширование. Рекомендуется использовать совместно с no-store,
                     т.к. иначе браузер может держать объект в истории и использовать его.
  Cache-Control: store - можно хранить копию на диске
  Cache-Control: no-store - нельзя хранить копию на диске или другом постоянном хранилище из соображений безопасности. Только в памяти.
  Cache-Control: max-age - время жизни в кеше до обязательной валидации, может игнорироваться настройками кеша.
  Cache-Control: must-revalidate - обязательно проводить валидацию, не должно игнорироваться
 Validation
Объект, хранящийся в кеше подлежит валидации на сервере в любом из перечисленных случаев
 
Cache-Control: no-cache (+ no-store)
Expires: <date in the past>
Cache-Control: max-age=<time to live< expired
Cache-Control: max-age=0
Cache-Control: must-revalidate
 Web server settings
Каждый web-сервер имеет свои настройки по умолчанию для cache-control,
причем в разных версиях они могут быть различными.
Поэтому, если хочется предсказуемого поведения, нужно все пропысывать в явном виде.
 
Note: некоторые модули, в т.ч. php session (см. ниже), а также фреймворки и
библиотеки могут 
иметь свои default'ные схемы управления кеширования. Обязательно проверяйте на этот счет
документацию. Иначе может оказаться, что кеширование в действительности не работает без видимой причины.
 Apache settings
Note: php session по умолчанию отменяет эти настройки!
 httpd.conf, apache.conf
 
# 5 minutes
ExpiresDefault A300
# 1 YEAR
<FilesMatch "\.(flv|ico|pdf|avi|mov|ppt|doc|mp3|wmv|wav)$">
ExpiresDefault A29030400
</FilesMatch>
# 1 WEEK
<FilesMatch "\.(jpg|jpeg|png|gif|swf)$">
ExpiresDefault A604800
</FilesMatch>
# 3 HOUR
<FilesMatch "\.(txt|xml|js|css)$">
ExpiresDefault A10800"
</FilesMatch>
<FilesMatch "\.(ico|gif|jpg|png|pdf|mp3|wav)$">
  ExpiresActive On
  ExpiresDefault "access plus 1 month"
  Header append Cache-Control "public, store, cache, no-validate"
  Header append Pragma "cache"
</FilesMatch>
<FilesMatch "\.(css|js)$">
  ExpiresActive On
  ExpiresDefault "access plus 1 week"
  Header append Cache-Control "public, store, cache, no-validate"
  Header append Pragma "cache"
</FilesMatch>
# 1 YEAR
<Directory "/var/www/date/libs">
  <FilesMatch "\.(js|css)$">
  ExpiresDefault A29030400
  Header set Cache-Control "max-age=290304000, public, store, cache, no-validate"
  </FilesMatch>
</Directory>
 PHP settings
В PHP модуль session по умолчанию полностью отключает кеширование. Необходимо поменять настройки
и заняться управлением кешем самостоятельно.
 php.ini
 
session.cache_limiter =
 
 
Либо нужно использовать 
session_cache_limiter()
 
 
В скрипте обработка кешируемых страниц выглядит следующим образом
 
if(function_exists("getallheaders")) {
  $headers = getallheaders();
}
$hash = get_page_hash();
if(isset($headers) && isset($headers["If-None-Match"])) {
  if(preg_match("/".$hash."/", $headers["If-None-Match"])) {
    header("HTTP/1.1 304 Not Modified");
    exit;
  }
}
header("ETag: \"{$hash}\"");
header("Cache-Control: public, store, cache, max-age=$timeout");
header("Expires: ".gmdate ("D, d M Y H:i:s", time()+$timeout)) ;
PHP cache control example 1
require_once('cache-ctl.php');
// Обработка запроса, определяем тип кеширования
// (CACHE_STATIC, CACHE_DYNAMIC, CACHE_NORMAL, CACHE_PRIVATE, CACHE_NEVER).
// Например, для POST это может быть CACHE_NEVER, а для GET - CACHE_PRIVATE или
// CACHE_NORMAL в зависимости от запроса.
// Вычисляем хэш ответа. Это может быть md5 от тела ответа, даты модификации или чего либо другого,
// однозначно идентифицирующее версию изменяющегося объекта.
cache_ctl_if_match($hash); // return 304 Not modified if necessary
cache_ctl($level, $timeout, hash); // set cache control headers
// do request output
PHP cache control example 2
require_once('cache-ctl.php');
// Предварительная обработка запроса, определяем тип кеширования
// и хэш для первой части ответа.
cache_ctl_preset($level, $timeout, $hash);
// Продолжаем обработку, возможно, формируем еще часть ответа
// (и строим для него отдельный хеш). Проверяем доп. условия, которые могут влиять на
// ответ и его кеширование.
cache_ctl_preset($level, $timeout, $hash);
// Теперь все факторы учтены, хэш вычислен, можно формировать заголовки.
// Перед этим проверяем, передал ли клиент хэш объекта и совпадает ли он с полученным нами.
cache_ctl_if_match(); // return 304 Not modified if necessary
cache_ctl(); // set cache control headers
// do request output
2017.01.06
 
 
 
See also: 
 
 FB
  or mail alterX@alter.org.ua (remove X)
   
  Share     |