Акселератор и кэширование документов в WWW
| |
|
На всех наших виртуальных серверах работает механизм ускорения
(acceleration).
Этот механизм давно применяется в MS IIS, и основан на кэшировании
наиболее используемых документов. Это весьма похоже на использование
proxy для доступа клиентов в Internet.
Все запросы из Internet попадают на прокси-сервер (акселератор), который
хранит наиболее часто используемые документы в своем дисковом кэше
или непосредственно в оперативной памяти. Если документа нет, или
запрос содержит подстроки "cgi" или "?", то делается обращение к
основному серверу, несущему все документы в оригинальном виде.
Используется ряд механизмов для поддержания актуальности кэшированных
документов, описанных стандартом HTTP/1.1 [1] Помимо этого, для поддержания
актуальности при работе с протоколом HTTP/1.0 используется ряд иных методов.
Чем чаще изменяется файл, тем меньше время его кэширования. При этом
файлы, закачиваемые по ftp, обновляются автоматически.
Также для принудительного обновления файлов можно
воспользоваться
SiteManager (доступен по URL http://domain_name/wmng.html)
Для мгновенного обновления в кэше файлов, измененных в unix-shell, можно
воспользоваться командой refresh. Запустите ее без параметров и файлы,
которые были изменены после последнего запуска refresh будут обновлены в
акселераторе немедленно. Если необходимо обновить только отдельный файл или
несколько файлов, перечислите их в качестве параметров к команде refresh.
Например, refresh index.html subdir/123.html pics/apple.gif. Путь следует
указывать относительно каталога ~/www.
Таким образом, если при обычной работе всего 50% посещений проходило
через различные прокси-серверы (за счет использования провайдерского
прокси посетителем сервера), то теперь все 100% запросов к Вашим
виртуальным серверам проходит через один или несколько прокси.
Обращаем Ваше внимание, что, несмотря на общее увеличение скорости работы,
полная перезагрузка сайта (Shift-Reload в Netscape или Ctrl-F5 в MSIE), будет
производится медленнее чем обычно, т.к. при таком запросе все документы и
изображения будут обрабатываться последовательно двумя компьютерами вместо
одного. Однако эта возможность браузеров обычно не используется посетителями.
При написании CGI-скриптов, особенно при вызове их из SSI, рекомендуем
научиться правильно управлять механизмами кэширования. Эти механизмы используются не
только в нашем proxy-accelerator, но и во всех остальных случаях, как-то
прокси на провайдере посетителя, прокси корпоративного интранета, механизм
кэширования браузера и так далее.
Для управления кэшированием статических документов мы рекомендуем воспользоваться
возможностями модуля Apache mod_expires [3], который позволяет формировать заголовки документов
согласно Вашим пожеланиям. Настройки можно будет делать индивидуально для каждой
директории. Модуль mod_expires уже включен в конфигурацию виртуального
сервера, нужно только указать правила его использования (см. ниже).
Рассмотрим пример типичного использования mod_expires на примере документов,
лежащих в корневой директории сервера www.host.ru.
Создадим файлы со следующими правами доступа:
-rw-r--r-- 1 testwww sadmin 160 11 фев 04:25 .htaccess
-rw-r--r-- 1 testwww sadmin 16401 11 фев 04:22 test.gif
-rwxr-xr-x 1 testwww sadmin 440 11 фев 04:24 test.html
-rw-r--r-- 1 testwww sadmin 17073 11 фев 04:23 test.jpg
Файл .htaccess содержит строки:
XBitHack on
DirectoryIndex test.html
ExpiresActive on
ExpiresByType image/jpeg "access plus 1 day"
ExpiresByType image/gif "now"
ExpiresByType text/html "now"
Тестовый документ test.html:
<html>
<title> mod_expires parameters test </title>
<body>
<center>
<font size="+7">
<!--#config timefmt="%D %T"-->
<!--#echo var="DATE_LOCAL"-->
</font size>
<br><spacer type=vertical size=100>
<a href="http://httpd.apache.org/docs/mod/mod_expires.html">
<img src=test.jpg alt="image/jpeg"></a>
<br><spacer type=vertical size=100>
<a href="http://httpd.apache.org/docs/mod/mod_expires.html">
<img src=test.gif alt="image/gif"></a>
</center>
</body>
</html>
Содержимое файлов test.jpg и test.gif значения не имеет - важен формат,
заданный в соответствии с расширением файла.
При обращении к этим файлам получаем следующие результаты
Тест 1 (запрос заголовка самого html-документа) :
$ telnet www.host.ru 80
Connected to www.host.ru.
HEAD / HTTP/1.1
Host: www.host.ru
HTTP/1.1 200 OK
Date: Sun, 11 Feb 2001 01:26:54 GMT
Cache-Control: max-age=0
Expires: Sun, 11 Feb 2001 01:26:54 GMT
Content-Type: text/html; charset=windows-1251
Тест 2 (заголовок при выдаче gif-картинки) :
$ telnet www.host.ru 80
Connected to www.host.ru.
HEAD /test.gif HTTP/1.1
Host: www.host.ru
HTTP/1.1 200 OK
Date: Sun, 11 Feb 2001 01:27:14 GMT
Cache-Control: max-age=0
Expires: Sun, 11 Feb 2001 01:27:14 GMT
Last-Modified: Sun, 11 Feb 2001 01:22:29 GMT
Content-Type: image/gif
Тест 3 (заголовок для jpeg-файла с установленным временем кэширования) :
$ telnet www.host.ru 80
Connected to www.host.ru.
HEAD /test.jpg HTTP/1.1
Host: www.host.ru
HTTP/1.1 200 OK
Date: Sun, 11 Feb 2001 01:27:37 GMT
Cache-Control: max-age=86400
Expires: Mon, 12 Feb 2001 01:27:37 GMT
Last-Modified: Sat, 11 Feb 2001 01:23:35 GMT
Content-Type: image/jpeg
Cледует обратить внимание на три обстоятельства:
1. Как видно, время в поляx "Expires:" и "Cache-Control:" при выдаче контента
установленo в значения в соответствии с параметрами .htaccess.
2. Для чистоты эксперимента специально установлен XBitHack (и права
доступа для test.html - chmod 755) для обработки SSI-инструкций в файле
с расширением .html - такие документы по умолчанию кэшируются акселератором.
3. Все приведенные примеры обращений к www.host.ru осуществлены
непосредственно через акселератор, производящий кэширование -
это позволяет проверить корректность выполненных настроек.
Hаконец, даже такой простой тест, как reload страницы в
браузере, показываeт, что текст с текущим временем меняется при каждой
перезагрузке страницы (не чаще раза в секунду), верхнее изображение
подгружается из кэша браузера (test.jpg), нижнее (test.gif) - принимается
c сервера при каждом обращении к документу.
В целях улучшения качества обслуживания посетителей Вашего www-сервера
целесообразно устанавливать время кэширования для статических документов,
например, изображений, на максимально возможный срок. Oсновную часть трафика
составляют именно изображения, и тем самым экономится время посетителей,
затрачиваемое на доступ к документам Вашего сервера: изображения будут
храниться в кэше браузера клиента, во всевозможных транзитных
прокси-серверах, в акселераторе и т.д. Например, если изображения изменяются
не чаще раза в три месяца, установите следующие параметры:
ExpiresActive on
ExpiresByType image/jpeg "modification plus 3 months"
ExpiresByType image/gif "modification plus 3 months"
Если Вы считаете, что Ваши CGI-скрипты вообще не надо кэшировать, то вставьте
в процедуру выдачи HTTP заголовков [2] следующие команды:
Пример на языке Perl:
use POSIX qw(strftime);
my $expireTime = strftime "%a, %e %b %Y %H:%M:%S GMT", gmtime(time());
print "Pragma: no-cache\n";
print "Cache-control: no-cache, must-revalidate\n";
print "Expires: $expireTime\n";
print "Content-type: text/html\n\n";
Пример на языке PHP:
<?php
header("Pragma: no-cache");
header("Cache-Control: no-cache, must-revalidate");
header("Expires: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Content-type: text/html");
?>
В случае, если изображение, равно как и документ с любым другим MIME-type,
формируется путем исполнения CGI-скрипта, обновляется с некоей периодичностью,
а не при каждом обращении, не нужно совсем запрещать кэширование такого
документа. Более правильным решением будет формирование соответствующих
заголовков документа динамически, устанавливая значения в известное время
следующего ожидаемого обновления документа, согласно заложенному в скрипт
алгоритму. Ниже приведен пример заголовков CGI-скрипта, данные для
которого обновляются каждые пять минут:
Пример на языке Perl:
use POSIX qw(strftime);
my $maxAge = 300;
my $expireTime = strftime "%a, %e %b %Y %H:%M:%S GMT",gmtime(time()+$maxAge);
print "Cache-control: max-age=$maxAge\n";
print "Expires: $expireTime\n";
print "Content-type: text/html\n\n";
Пример на языке PHP:
<?php
$maxAge = 300;
$expireTime = gmdate("D, d M Y H:i:s", time()+$maxAge);
header("Cache-Control: max-age=$maxAge");
header("Expires: $expireTime GMT");
?>
Ссылки:
[1]
RFC2616: Кеширование в HTTP
[2]
Описание заголовков HTTP, управляющих кэшированием
[3]
Apache mod_expires documentation