Комментарии 16
А что с гонкой? Вы пробовали ab в 5 потоков. Полагаю, у вас больше одного nginx-воркера и больше одного fpm. Не смотрели, сколько раз фактически выполнился скрипт?
Я имею в виду, пока кэша не существует, но другой воркер прямо сейчас обрабатывает запрос, который может вернуть нужный результат, то как эту ситуацию разрулит nginx?
Интересно, а если у меня статический сайт отдается nginx, будет ли какой-прирост если отдавать его через кеш? Куда он кеширует в память или на диск?
Хмм, вместо if лучше использовать map
Эти 3 условия мы запишем так (в контексте server):
set $no_cache 0; if ($request_method != GET) { set $no_cache 1; } if ($query_string != "") { set $no_cache 1; } if ($request_uri != "/") { set $no_cache 1; }
Вы проверили 1-й if, если значение истинно унаследовали внешнюю конфигурацию, проверили 2-й if, снова унаследовали внешнюю конфигурацию, проверили 3-й…
Тем самым при каждом запросе подпадающим под все три условия трижды наследуете конфигурации предыдущего уровня.
Как минимум их надо дополнить директивами break, чтобы избежать 3-йной проверки.
Как максимум:
Только главную страницу, то есть переменная $request_uri должна иметь значение "/".
Вынести обработку в отдельный location "=/"
Запросы типа GET и никакие другие. Следовательно значение переменной $request_method должно равняться GET.
Описать соответствующую директиву в map
Только те запросы, в которых нет GET параметров. Значит переменная $query_string должна содержать пустую строку "".
Использовать $query_string ($args) непосредственно в директивах fastcgi_cache_bypass и fastcgi_no_cache без всяких проверок в if.
Зачем в ключ добавлять метод запроса
fastcgi_cache_key "$scheme$request_method$host$request_uri$cookie_codeAuth";
если дальше идет блок условия
if ($request_method != GET) {
set $no_cache 1;
}
А зачем в ключе схема?
fastcgi_cache_key "$scheme$request_method$host$request_uri$cookie_codeAuth";
В текущих реалиях, на production сервере будет использоваться только одна схема — https, так зачем она в ключе? Хотя если проект большой и фронтенд-серверов там несколько, стоящих за каким-нибудь балансировщиком (тот же nginx или haproxy), то https может быть только в мир, а коммуникация с многочисленными фронтами может быть по http, но и в этом случае схема всегда будет только какая-то одна.
Вот так писали в 2011-м
set $no_cache 0;
if ($request_method != GET) {
set $no_cache 1;
}
if ($query_string != "") {
set $no_cache 1;
}
if ($request_uri != "/") {
set $no_cache 1;
}
Вместо кучи блоков if надо использовать директиву map (map'ов тоже может понадобится несколько), автор nginx уже много раз писал и говорил об этом. Использование большого количества условий if — это заботливо разложенные на поле грабли, на которые вы обязательно наступите в будущем.
Ну и еще было бы неплохо в статье упомянуть про такие параметры: fastcgi_cache_min_uses, fastcgi_cache_lock, fastcgi_cache_lock_timeout, fastcgi_cache_use_stale, fastcgi_cache_background_update
Вместо кучи блоков if надо использовать директиву map (map'ов тоже может понадобится несколько), автор nginx уже много раз писал и говорил об этом. Использование большого количества условий if — это заботливо разложенные на поле грабли, на которые вы обязательно наступите в будущем.
В контексте server никаких граблей с использование if нет. Данный код не вызовет чего-то неожиданного, за исключением этого.
Ну, для отдельного элемента это будет примерно так:
proxy_cache_key "$host$request_filename";
...
location ~ /drop(/.*) {
allow ***;
deny all;
proxy_cache_purge images "$host/usr/share/nginx/html$1";
}
...
Ну а использование, если у вас закэширован документ по адресу
example.com/a/b/c.jpg
, нужно просто сделать GET-запрос по адресу example.com/drop/a/b/c.jpg
Ну а весь кэш — ну, скорее всего только ручками дропнув содержимое директории которая указана в proxy_cache_path
Использование Nginx FastCGI Cache