Кеширование контента на стороне клиента
Unix 12.02.2010Как я уже писал, у меня работа сейчас связана с Unix’ами.
Очень часто получается такая фишка, что сервер трафик отдает не сильно, но загрузка винтов капитальная. Или даже трафик еще и капитальный при этом.
Решить такое далеко не простая задача, но возможная.
Как минимум надо определить что грузит сервер (винта, память, куча процессов и т.д.) ну и плюс, что за контент на сервере (статические html, скрипты php/perl/cgi, картинки, видео или запросы к базе данных).
Универсальный способ я расписывать не буду – его нет. Но в этой заметочке хотелось бы описать работу заголовков HTTP запросов и тому как на них реагирует сервер. А главное, какое это все отношение имеет к кешированию и убиранию нагрузки.
Сразу хочу упомянуть тут пару ссылочек, почитав, которые я сам вразумил некоторые моменты, но, конечно же, больше они помогли в плане узнать как люди решали те или иные задачи:
http://nomagic.ru/article.php?aid=58
http://www.seoblog.com.ua/2009/01/21/kak-uvelichit-skorost-zagruzki-sajjta-i-umenshit-trafik/
Надеюсь, авторы на меня не будут в обиде, т.к. текст сам я тут не привожу, но ссылки на их сайт даю.
Зачем нужны заголовки и как это решает проблему кеширования контента?
Прикол в том, что клиентский браузер умеет, и главное, это делает каждый последующий раз (кроме первого), отсылать на Web сервер заголовки If-Modified-Since. Именно отсылать! И это главное. Т.е. клиентский браузер не только принимает заголовки от сервера.
Что в этом такого? А вот что. Когда браузер клиента первый раз приходит на какую-то страничку он получает контент и сохраняет его у себя на диске (надеюсь, сохраняет). При дальнейшем посещении этой же странички (или других страничек в которых есть ссылки на файлы из первой странички) браузер смотрит, что у него есть в кеше и отсылает серверу хидер If-Modified-Since, в котором указывает, что у него есть и когда он у него появился. Не буду вдаваться в технические подробности, но сервер, если умеет обрабатывать такие хидера или подобные механизмы (описанные на страничках по ссылкам выше) смотрит в то, что у него изменилось или нет и отдает клиенту ответ/хидер о том, есть ли изменения или нет. Если таковых нет, то клиентский браузер просто подтягивает этот конктент со свего кеша и не перезапрашивает у Web сервера этот контент.
Что это нам дает? Очень просто – трафик снижается (а он не бесплатный в большинстве случаев), запросов к винту/базе меньше (в дальнейшем не надо тратиться на апгрейд сервера), все довольны. Клиент особо в обиде не будет, т.к. он тоже обрадуется тому, что страничка отдаваться стала быстрее, или попросту, задержка стала меньше. Ему ж не обязательно знать, что контент вообще с его же диска загрузился.
Кто задается вопросом, а что будет если контент на Web сервере поменялся? А очень просто – Web сервер посмотрит на хидер присылаемый от клиента, увидит там разницу между тем, что у него есть и тем, что ему прислали и просто переотдаст контент по-новой.
Самое главное, работа заголовков тут описана только для Web сервера Apache (любой версии). В нем обязательно должны быть включены несколько модулей:
mod_headers
mod_expires
mod_gzip (для статьи из сслок выше)
Конечно же, если бы все так было просто, то почему же все так не делают и это не описано в каком-нить readme.txt к инсталляции Web сервера?
- Такой метод может снизить нагрузку на трафик/винты/базу и т.д., но не на всех типах сайтов. Слишком часто изменяющийся контент сводит на нет все штуки с хидерами (заголовками).
- Проще всего операции с выдачей хидеров и их обработкой apach‘у задавать из .htccess, но фишка в том, что сам парсинг и каждая директива сервера достаточно не мало его грузит. Т.е. делать тупо в корне сайт такую штуку лучше не стоит. Если, конечно, сайт сайт не сильно грузит сервер, или на него трафик не большой. Некую середину в таком решении можно сделать так, что файлик .htaccess лучше класть только в те дирректории сайта, которые чаше всего используются, но реже всего обновляются сами файлы в этой директории.
- Операции с хидерами (заголовками) могут выиграть порядка 20%-60% в скорости загрузки странички. НО! Не стоит натравливать для проверки сработало это или нет, всякие “умные” боты и сайты для проверок скорости. Все очень просто – большинство из этих сайтов, не отрабатывают тем с хидерами и всегда тупо перезапрашивают весь контент, что есть на страничке.
- ЗАМЕЧЕНО, что GoogleBot может не передавать заголовок If-Modified-Since на сервер. Хотя на том же Google написано, что он этот заголовок выставляет (проверяли через tcpdump и ngrep). Это относиться к тем пользователям, которые хотят, чтобы тот же GoogleBot поменьше “шерстил” контент у них на страничках и на “вгружал” сервер по самые помидоры из-за этого.
В одной статье из линков выше, так же рассматривается вариант ужимания потока через gzip на отдаваемом Web сервере контенте. Замечу сразу, что это будет заметно только на всяческом текстовом контенте (html,php,perl,cgi) чем на картинках или видео.
Там же, рассматриваются варианты того, чтобы If-Modified-Since вообще игнорировать, но при этом использовать другой метод обработки хидеров для снижения нагрузки на сервер. Очень не плохой метод. Не проверял. Возможно, как раз такое, сработает на всяческих GoogleBot‘ах.
В любом случае, Вы сами можете поиграться с вариантами какой из методов работы с заголовками лучше для Вашего Web сервера.
Больше о директивах самого Apach‘а по теме работы If-Modified-Since описано тут: http://httpd.apache.org/docs/2.0/mod/mod_expires.html
Вот один пример использования кеширования через mod_expires и mod_headers в apach’e:
### активация mod_expires
ExpiresActive On
### Проэкспайряться файлы.gif’s спустя 1 месяц с момента последнего доступа
ExpiresByType image/gif A2592000
### Проэкспайриться все спустья 1 день с момента последней модификации файла
ExpiresDefault “modification plus 1 day”
### Вписать в хидере Cache-Control в файл index.html
< Files index.html >
Header append Cache-Control “Publich, must-revalidate”
< /Files>
В примере мы видим, что в строке где описан 1 месяц используется, во-первых, только секунда, во-вторых, модификатор “A”.
В этой команде можно применять только два модификатора: “A”, “M”. Что будет означать: “A” – access time (т.е. время последнего доступа к файлу), “M” – modification time (время последней модификации).
Но опять же, подробней о модификаторах и использовании лучше читать по ссылке выше на apache.org.
Постараюсь, что-то найти на эту тему как эту обработку сделать на nginx. Т.к. как ни крути, но nginx достаточно мощный, быстрый и классный web сервер, особенно для статического контента (картинки, видео). А как раз в паре с обработкой заголовков, я думаю, что нагрузка на этом Web сервере должна еще больше уменьшиться.
(добавлено: 16.02.210)Вот то, что удалось найти на nginx:
http://habrahabr.ru/blogs/hi/72539/
Как обычно, дают только ссылку, перепечатывать тут не буду – не хочу нарушать авторство, тем более, что человек высказал свою идею по этому вопросу. И высказал достаточно хорошо.
Свежие комментарии