Как стать автором
Обновить

nginx, ещё раз про кэширование

Время на прочтение3 мин
Количество просмотров14K
Иногда скорость роста проекта несколько выше чем скорость оптимизации веб-приложения или приобретение более мощного оборудования под backend.

Наиболее простая схема «распараллеливания» нагрузки — вынос основной нагрузки на несколько frontend. Раньше приходилось мучиться (или наслаждаться, кому как) с webdav'ами, кластерными ФС и прочими хитростями чтобы обеспечить актуальную информацию, так было до тех пор, пока не появился nginx, а точнее proxy_store и proxy_cache в нём.



В общем случае, схема работы выглядит следующим образом:
Несколько frontend (дешевые сервера без raid и прочих взрослых примудростей) через round robin отдаются клиентам.
frontend отдаёт с себя статику, проксирует и отдаёт с себя кэшированную динамику для гостей и осуществляет прозрачное проксирование для зарегистрированных пользователей.
ТТХ backend в данном случае большого значения не имеет, вопрос правильной конфигурации его нужно обсуждать индивидуально. Дополнительное кэширование всего чего можно на backend приветствуется.

Преимущества такого подхода — в стоимости данной «кластеризации» за счёт бюджетных характеристик frontend. Отказ любого frontend не критичен, достаточно поднять его ipшку (при наличие такой возможности) на другом frontend или изменить конфигурацию DNS (что может чревато недоступностью для ряда пользователей). На практике, городской портал где видео\фото хранилище на 4Тбайт (занято на backend) на frontend'ах лежит не более 300Гбайт того, что реально запрашивают пользователи (чистить можно по atime но учитывая, что на frontend ФС монтируется с noaime то по дате создания файла). Статичное содержимое на backend генерируется с новым именем, модификация файла также приводит к созданию нового имени файла, чтобы frontend корректно работал.

http {
proxy_cache_path /var/www/cache levels= keys_zone=mycache:150m;
...
}

server {
#устанавливаем дефолтовый флаг, не кэшировать
set $cached 0;
listen server;
server_name server *.server;
#нужно чтобы отдавать красивую 500Ашипку с себя
error_page 502 503 504 509 /500.html;
#если где-то что-то забыли, то будет работать схема прозрачного проксирования
error_page 404 = @nocached;

expires epoch;
root /var/www/html;

location = /500.html {
}

#динамику будем брать с frontend и если отсутствует, то скачивать
location ~* ^.+\.(jpg|jpeg|gif|gz|zip|flv|rar|wmv|avi|css|swf|png|htc|ico|mpeg|mpg|txt|mp3|mov|js)$ {
expires 1y;
error_page 404 = @fetch;
}

#кэшируем статику на себя
location @fetch {
proxy_pass httр://backend;
proxy_store on;
proxy_temp_path /var/www/_fetch;
proxy_set_header Host mydomain;
proxy_set_header If-Modified-Since "";
}

#для зарегистрированных проксируем прозрачно
location @nocached {
proxy_pass httр://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

#гостям проксируем и кэшируем
location @cached {
proxy_pass httр://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache mycache;
proxy_cache_valid 200 301 302 304 5m;
proxy_cache_key "$request_method|$http_if_modified_since|$http_if_none_match|$host|$request_uri";
proxy_hide_header "Set-Cookie";
proxy_ignore_headers "Cache-Control" "Expires";
}

#иначе морда домена не будет работать
location = / {
return 404;
}

location / {
#если нет нашей куки
if ($http_cookie !~ "userid" ) {
set $cached 1;
}

if ($request_method = POST) {
set $cached 0;
}

if ($request_method != GET) {
set $cached 0;
}

if ($cached = 1) {
error_page 404 405 502 504 = @cached;
break;
}

if ($cached = 0) {
error_page 404 405 502 504 = @nocached;
break;
}

}

}


Всё это дело служит на благо моего новосибирского сайта
Теги:
Хабы:
Всего голосов 53: ↑49 и ↓4+45
Комментарии27

Публикации

Истории

Ближайшие события

19 августа – 20 октября
RuCode.Финал. Чемпионат по алгоритмическому программированию и ИИ
МоскваНижний НовгородЕкатеринбургСтавропольНовосибрискКалининградПермьВладивостокЧитаКраснорскТомскИжевскПетрозаводскКазаньКурскТюменьВолгоградУфаМурманскБишкекСочиУльяновскСаратовИркутскДолгопрудныйОнлайн
3 – 18 октября
Kokoc Hackathon 2024
Онлайн
24 – 25 октября
One Day Offer для AQA Engineer и Developers
Онлайн
25 октября
Конференция по росту продуктов EGC’24
МоскваОнлайн
7 – 8 ноября
Конференция byteoilgas_conf 2024
МоскваОнлайн
7 – 8 ноября
Конференция «Матемаркетинг»
МоскваОнлайн
15 – 16 ноября
IT-конференция Merge Skolkovo
Москва
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань