У меня 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
. Однажды я сделал это, у меня были хиты кеша.