Назад | Перейти на главную страницу

Почему эта настройка Nginx не кеширует ответы?

У меня Nginx сидит перед gunicorn, который, в свою очередь, находится перед django применение.

Основной вопрос: «Почему мои ответы не кэшируются?» Тем не менее, я довольно зеленый в этом вопросе, поэтому вот мои предположения о том, что должен случиться (в случае, если мое основное понимание ошибочно).

Запрос A хиты Nginx просят, скажем, некоторых json из службы REST. У Nginx этого нет в кеше, поэтому он передает его Gunicorn/Django. Генерируется ответ, который передается обратно через Nginx, где он кэшируется, и, наконец, возвращается клиенту.

Затем!

Запрос B приходит в запросе того же ресурса. Nginx хранит его в кеше и поэтому обслуживает его напрямую, никогда не затрагивая приложение django.

Основываясь на этом предположении и после долгого чтения, я получил эту минимальную конфигурацию nginx в моем sites-enabled:

proxy_cache_path /tmp/nginx keys_zone=one:20m inactive=60m;
proxy_cache_key "$host$request_uri";


server {
    listen 8080;
    server_name localhost;

    proxy_cache one;

    location / {
        add_header X-Proxy-Cache $upstream_cache_status;
        proxy_ignore_headers X-Accel-Expires Expires Cache-Control;
        proxy_pass http://127.0.0.1:8000;
    }
}

Этот код основан на документации для кеширование nginx, и учебник Вот.

Если я проверю несколько запросов, я получу такой ответ:

curl -X GET -I http://localhost:8080

HTTP/1.1 200 OK
Server: nginx/1.4.6 (Ubuntu)
Date: Wed, 06 May 2015 01:35:38 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Cookie
X-Frame-Options: SAMEORIGIN
Set-Cookie: csrftoken=b6UG5X4ZlGwVUYfHSIkq4PKBIxicpWxc; expires=Wed, 04-May-2016 01:35:38 GMT; Max-Age=31449600; Path=/
X-Proxy-Cache: MISS

Примечание. Я думаю, что с файлом cookie все в порядке, поскольку я не включаю его в cache_key директива. Хотя я мог ошибаться.

Несмотря на многочисленные запросы одного и того же ресурса, я никогда не получаю попадания в кеш. Далее, файлы кеша не записываются в proxy_cache_path каталог.

Может ли кто-нибудь указать мне, почему ответы не кешируются?

Спасибо!

Попытка кэшировать объект, содержащий Set-Cookie заголовок - довольно плохая идея. Это изначально запрещено от nginx, если не указано proxy_ignore_headers директива.

Этот заголовок игнорируется плюс Vary: Cookie Заголовок в ответах сделает ваш кеш совершенно неэффективным, поскольку единственный ресурс будет иметь столько записей в кеше, сколько посетителей просят его.

Также обратите внимание, что Vary заголовок учитывается в алгоритме кеширования с версии 1.7.7 только. Использование предыдущей версии nginx с proxy_ignore_headers Set-Cookie; приведет к массовому дублированию файлов cookie, поскольку Set-Cookie заголовок из кэшированного ответа будет отправлен обратно всем запросам, попадающим в запись кеша.

Мне кажется, проблема в том, что вышестоящий сервер просто не отправляет ответ, содержащий дату истечения срока действия (Expires:) или валидатор кеша (например, Last-Modified:). (Срок действия cookie не имеет ничего общего с кешированием.)

В Спецификация HTTP 1.1 говорит:

Если нет ни валидатора кеша, ни явного срока действия, связанного с ответом, мы не ожидаем, что он будет кэширован, но некоторые кеши МОГУТ нарушить это ожидание (например, когда доступ к сети ограничен или отсутствует).

(Курсив добавлен.)

Похоже, в вашей настройке Django не включено кеширование. Я предлагаю тебе включить кеширование на уровне сайта. Если вы это сделаете, Django сгенерирует в своем ответе заголовки, которые нужны Nginx для кеширования.

Другой вариант - использовать proxy_cache_valid в вашей конфигурации Nginx. Я использовал настройку, похожую на вашу, и воспроизвел полученное вами поведение, затем добавил proxy_cache_valid any 5m; который сообщает Nginx кэшировать ответы с любым кодом состояния (any) на 5 минут 5m. Однажды я сделал это, у меня были хиты кеша.