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

Комментарии 16

А что с гонкой? Вы пробовали ab в 5 потоков. Полагаю, у вас больше одного nginx-воркера и больше одного fpm. Не смотрели, сколько раз фактически выполнился скрипт?
Я имею в виду, пока кэша не существует, но другой воркер прямо сейчас обрабатывает запрос, который может вернуть нужный результат, то как эту ситуацию разрулит nginx?

Это решается с помощью fastcgi_cache_lock (fastcgi_cache_lock_age, fastcgi_cache_lock_timeout с ними же).

Интересно, а если у меня статический сайт отдается nginx, будет ли какой-прирост если отдавать его через кеш? Куда он кеширует в память или на диск?

Прироста не будет, это же fast-cgi cache.

Для статики вы можете разве что включить sendfile. Но и так всё хорошо кэшируется на уровне page cache

Хмм, вместо 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.
Такое впечатление, что статья пролежала в черновиках лет 9 минимум. Начиная от банальности написанного — уже заканчивается 2020-й год и про fastcgi-кэш было написано сотни раз на множестве тематических сайтов, и заканчивая массовым применением if в конфиге nginx.

Зачем в ключ добавлять метод запроса
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

Стоит отметить, что директивы proxy_cache_purge нет в бесплатном nginx, но можно собрать nginx из исходников с модулем ngx_cache_purge, чтобы она появилась.

Да, действительно, вы правы! Совсем забыл что у нас он собран с этим модулем.

НЛО прилетело и опубликовало эту надпись здесь
Не надо вручную назначать, nginx сам создает эту директорию с нужными правами при запуске.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Изменить настройки темы

Истории