Главная > Теория и практика > Используем Nginx, как кеширующий сервер

Используем Nginx, как кеширующий сервер

nginx

В этой статье рассмотрим применениt Nginx’a в качестве кеширующего сервера. Подробно о HTTP кеширования написано в статьях о продвинутом кеширующем сервере Varnish. Сразу следует отметить, что Nginx полностью не заменяет Varnish по функционалу и возможностям, но тем не менее продставляет очень хорошое решение. Учитывая великолепную работу этого Web-сервера, наличие функциональности кеширования делает возможным подключить ее к своему сайту буквально за 2 минуты.

Что кешировать?

В предыдущих статьях уже неоднократно упоминалось про суть HTTP кеширования. Если не учитывать более сложных случаев, когда нужно учитывать персонализацию страниц, почти на всех сайтах можно кешировать странички для неавторизованных пользователей. Этот метод хорошо подойдет для информационных ресурсов (например, для этого блога).

Самый простой случай - кешировать страницы для неавторизованных пользователей. Время кеширования обычно выбирают небольшое - 5…10 минут. Тем не менее, при большой нагрузке, это может сэкономить огромное количество ресурсов.

Как кешировать с помощью Nginx?

Давайте вместе настроим кеширование для нашего блога. Для начала необходимо определить зоны кеширования. Зоны помагают категоризировать Ваши объекты в кеше для лучшей управляемости. Зона имеет имя и размер (nginx.conf):

#...
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=all:32m;
# include virtual hosts...

Так мы определили, что хотим создать зону “all” размером 32Мб, данные которой будут храниться в папке “/var/cache/nginx”. Параметр levels задает уровень вложенности файлов. В нашем случае файлы будут храниться в друхуровневой структуре папок. Подробнее про параметры можно почитать в официальной документации.

Не забываем создать папку, где будут храниться данные кеша:

mkdir /var/cache/nginx

Теперь необходимо выделить принимающий сервер и настроить на нем правила кеширования:

server {
        listen 80;
        server_name .highload.com.ua;

        location / {
                if ($http_cookie ~* "comment_author_|wordpress_(?!test_cookie)|wp-postpass_" ) {
                        set $do_not_cache 1;
                }
                proxy_cache_bypass $do_not_cache;
                proxy_pass http://highload.com.ua:81/;
                proxy_cache all;
                proxy_cache_valid 404 502 503 1m;
                proxy_cache_valid any 1h;
        }
}

Обслуживающий хост уедет на 81 порт. Нам необходимо, чтобы кеширование работало только для неавторизованных пользователей. Некоторые пояснения к настройкам:

В условие “if” сделана проверка на куки, которые Wordpress ставит при авторизации

proxy_cache_bypass $do_not_cache - не кешировать ответ, если пользователь авторизован

proxy_cache all - этот параметр включает кеширование, в качестве аргумента принимает зону (у нас это “all”)

proxy_cache_valid 404 502 503 1m - кешируем 404, 502 и 503 ответы на 1 минуту

proxy_cache_valid any 1h - кешируем все остальные ответы на 1 час

Другие форматы

Следует отметить, что кешировать можно не только страницы HTML, но и любые другие типы данных. На одном из наших проектов мы успешно кешируем уменьшенные версии картинок с помощью Nginx’a.

Будет интересно увидеть отзывы читателей, которым уже приходилось на практике применять это решение.

Google Bookmarks Digg I.ua Ru-marks Ruspace Zakladok.net Reddit delicious Technorati Yahoo My Web News2.ru БобрДобр.ru Memori.ru rucity.com

Статьи по теме

  1. 3 Декабрь 2010 в 21:34 | #1

    длинные листинги не возможно прочитать полностью: http://img140.imageshack.us/img140/1463/20101203212836.png

  2. 3 Декабрь 2010 в 22:31 | #2

    Активно используем кэширование nginx для форума (с той разницей, что используем fastcgi_cache_xxx, а не proxy_cache). Но вот заставить скрипт кэшировать картинки в такой конфигурации не получается — в кэш они не попадают.

  3. 4 Декабрь 2010 в 00:07 | #3

    Можно было бы еще вспомнить cache manager, который запускается отдельным процессом при старте нгинкса и проходится по всему кэшу. Все это асинхронно и в фоне, но ксли кэш очень большой (30-40гб), то проход по всему кэшу займет несколько часов и будет генерировать большой disk io.
    Мы эту проблему решили редактированием сорцов и увеличением интервала между каждой записью в кэше.

  4. 4 Декабрь 2010 в 02:08 | #4

    Я использую fastcgi_cache - http://adw0rd.ru/2010/nginx-fastcgi-cache/. Сейчас кеширую только главную страницу, попробую применить ваш if с кукой, спасибо!

  5. 6 Декабрь 2010 в 13:54 | #5

    fastcgi_cache_bypass $cookie_NAME $arg_nocache;
    fastcgi_no_cache $cookie_NAME $arg_nocache;

  6. 8 Декабрь 2010 в 21:12 | #6

    Некоторые мысли относительно конфигурации:

    1. Очень желательно задать proxy_temp_path (почему - тут [1])
    2. ИМХО если URI в location совпадает с URI в proxy_pass, то лучше его не задавать - так его nginx не обрабатывает, а передает в неизменном виде ([2]). Предполагаю, что это экономит процессорное время.
    3. proxy_cache_bypass задает какие запросы не надо брать из кеша. Если я правильно понимаю (не проверял), то в приведенной конфигурации ответы, полученные от бекенда и подпадающие под proxy_cache_bypass, все же будут записываться в кеш. Это бесполезно и надо их исключить с помощью proxy_no_cache.

    [1]: http://sysoev.ru/nginx/docs/http/ngx_http_proxy_module.html#proxy_cache_path
    [2]: http://sysoev.ru/nginx/docs/http/ngx_http_proxy_module.html#proxy_pass

  7. mstar
    12 Декабрь 2010 в 18:12 | #7

    ne podoashla mne konfiguraciya. pochemuto v kesh dobavlyayutsya takge i stranici ot zaloginennih yuzerov.

    tak poidee ne dolgno bit’.

  8. mstar
    13 Декабрь 2010 в 11:16 | #8

    Почему-то предидущий комент удалили, пишу повторно.

    Глючит ваша конфигурация, по крайней мере у меня на сервере. Багов 2:
    - в кеш добавляются страницы залогиненных юзеров, то есть гостям потом показываются залогиненные левые страницы
    - при длинных урлах - часть страницы не показывается, вместо него отображается сам урл.

  9. mstar
    13 Декабрь 2010 в 11:18 | #9

    Ха, тольои баг кеша, то ли так надо: после добавления повторного комента - старый комент показался. Но при открытии в чистом броузере - комента нет :) Если нужно, могу скрины приложить. Но так быть не должно, кеш надо уменьшать или хотя бы автору показывать, что его комент уже есть и повторный не нужно строчить.

  10. 10 Январь 2011 в 18:28 | #10

    Есть определенные проблемы при настройке nginx cache но они того стоят.
    Даже habrahabr.ru недавно переехал, из-за чего хватало проблем с комментариям, войти и выйти.
    Первое что нужно решить, это правильно настроить кеш для анонимных пользователей.
    Иначе могут увидеть страницу другого пользователя, или даже админа, с админкой.
    Решается обычно посредством куков, или если позволяет структура проекта, через location, кешируется зоны которые где только анонимные пользователи.
    А вот как кешировать и обновлять страницы для зарегистрированных пользователей это как по мне больше связано с собственными движками, или доработками.
    Кто-то просто добавляет сообщение “Ваш комментарий появиться в течении 5 минут, после обработки”, и время кеша стоит 5 минут у них. Кто-то дописывает побольше, так что при изменение на странице вызывается очистка кеша.
    Также никто не отменял поблочное кеширование.

    Пару советов тем кто будет пытаться настроить кеширование.
    Для авторизированных пользователей и управления кешем вам не обойтись без использования
    fastcgi_cache_key “$request_method|$host|$url”;#это в качестве примера, удобные для меня параметры.
    Конечно лучше подробнее почитать документацию, и тестировать.

    Если все плохо но по прежнему не кешируется. Поможет небольшой костыль для 100% кеширования !!! будьте аккуратны.
    fastcgi_hide_header “X-Powered-By”;
    fastcgi_pass_header “Set-Cookie”;
    fastcgi_ignore_headers “Cache-Control”;
    add_header “Cache-Control” max-age=900;

    И последнее, если вы хотите поиграться вдоволь, то думаю вы будете отдельные параметры давать на статические странички, отдельные на комментарии, и новые статьи, и т.д.
    Вот тут явно не будет лишним добавить свой заголовок, чтобы вы видели при настройки и после откуда вам отдалась страничка.
    add_header “Ваша метка” значение;

    На всякий случай, fastcgi можно заменить на proxy, все остальное сохраняется, NGINX рулит. Кеш во всей красе вам не только позволят снят нагрузку, но и во время обновлений, работы с MySQL и прочими службами, ваши пользователя вместо сообщения о технический работах, или ошибки, смогут все равно увидеть страничку, и прочитать содержимое.

  1. 3 Декабрь 2010 в 21:27 | #1