Вопрос или проблема
Я настроил обратный прокси-сервер NGINX с сервером кэширования NGINX (70:1652), который проксирует мой сервер Django Rest API, который выступает в роли исходного сервера (80:8080).
Кэширование не работает, когда я указываю следующие директивы для каждого блока location внутри исходного сервера NGINX, который слушает на порту по умолчанию для API Django 80:8080.
add_header Cache-Control "max-age=2629746, public";
Но кэширование работает внутри блока сервера кэширования, который проксирует исходный сервер выше, когда я указываю следующие 2 строки:
proxy_cache_valid 200 302 36M;
proxy_cache_valid 404 10m;
с сохранившейся ранее
add_header Cache-Control “max-age=2629746, public”; все еще в блоке исходного сервера.
Вот мой nginx.conf:
worker_processes auto;
events {
worker_connections 1024;
}
http {
log_format custom '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" $request_time';
# Логи доступа и ошибок
access_log /var/log/nginx/access.log custom;
error_log /var/log/nginx/error.log;
default_type application/octet-stream;
include /etc/nginx/mime.types;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 4096;
client_max_body_size 50M;
# Обратите внимание, что эти параметры определены вне блока сервера, хотя это не обязательно
proxy_cache_path /tmp/nginx levels=1:2 keys_zone=my_zone:10m inactive=60m;
proxy_cache_key "$scheme$request_method$host$request_uri";
## Блок сервера кэширования --> 70:1652. Сидит перед исходным API сервером.
server {
listen 1652;
charset utf-8;
source_charset utf-8;
server_name cachingserver;
# Логи доступа и ошибок
access_log /var/log/nginx/cachingserver.access.log custom;
error_log /var/log/nginx/cachingserver.error.log;
location / {
proxy_pass http://my-django-rest-api/;
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_set_header X-Forwarded-Proto $scheme;
proxy_cache my_zone;
add_header X-Proxy-Cache $upstream_cache_status;
proxy_buffering on;
# Поддержка WebSocket (nginx 1.4)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
upstream my-django-rest-api {
server 172.16.16.6:8080;# Внутренняя служба API Django, работающая в качестве исходного сервера.
}
## Блок сервера API ИСХОДНЯ --> 80:8080. Этот блок слушает на стандартном порту Rest-api 8080.
server {
listen 8080;
charset utf-8;
source_charset utf-8;
server_name originserver;
# Логи доступа и ошибок
access_log /var/log/nginx/originserver.access.log custom;
error_log /var/log/nginx/originserver.error.log;
location / {
try_files $uri $uri/ =404;
}
# Медиа: изображения, иконки, видео, аудио, параметры кэширования HTC
# Регулярное выражение без учета регистра (~*) для данного местоположения для указанных расширений.
location ~* /media/\.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|mp3|ogg|ogv|webm|htc|woff2|woff|m3u8|mpd|mss|aac|mp3)$ {
# Укажите длительность кэширования
# expires 12M;
access_log off;
# max-age должен быть в секундах
add_header Cache-Control "max-age=2629746, public";
}
# CSS и JavaScript & Python.
# Изображения, а также в соответствии с настройками Django. Необходимо периодически выполнять manage.py collectstatic на стороне Django.
# location ~* \.(?:css|js|py|jpg|jpeg|gif|png|ico|cur|gz|svg|svgz)$ {
location ~* /static/\.(?:css|js|py)$ {
# Укажите длительность кэширования
# expires 12M;
access_log off;
add_header Cache-Control "max-age=2629746, public";
}
# Документ html и данные
location ~* /\.(?:manifest|appcache|html?|xml|json|pdf)$ {
# Укажите длительность кэширования.
# expires -1;
# expires 12M;
add_header Cache-Control "max-age=2629746, public";
}
# Лента
location ~* /\.(?:rss|atom)$ {
# expires 1h;
add_header Cache-Control "max-age=2629746, public";
}
}
}
Мой вопрос:
Почему add_header Cache-Control “max-age=2629746, public”; не кэширует файлы и возвращает MISS в Postman? То есть Postman возвращает MISS для X-Proxy-Cache с указанным выше, когда я обращаюсь к кэш-серверу на порту 70?
С другой стороны, он регистрирует HIT с proxy_cache_valid, когда он указан внутри блока сервера кэширования, сохраняя add_header Cache-Control “max-age=2629746, public”; в качестве такового в блоках location исходного сервера.
Что я делаю не так?
Ответ или решение
Чтобы понять, почему директива add_header Cache-Control "max-age=2629746, public";
не приводит к кэшированию файлов в вашем NGINX Reverse Proxy, сто́ит проанализировать несколько моментов в конфигурации.
Кэширование в NGINX
Кэширование в NGINX работает на основе статуса HTTP ответа и заголовков, которые передаются от исходного сервера (Origin). Основные моменты, которые нужно учитывать:
-
Директивы
add_header
и их влияние: Заголовки, добавленные с помощьюadd_header
, будут отправляться клиенту, но это не влияет на кэширование ответов. Кэширование контролируется директивамиproxy_cache
,proxy_cache_valid
и другими кэширующими настройками. -
Важность статусов: Директивы
proxy_cache_valid
используются для определения того, какие коды состояния HTTP разрешают кэширование. Если ваш сервер возвращает статус ответа, который не совпадает с определениями вproxy_cache_valid
, кэширование не произойдет. -
Кэширование в Reverse Proxy: Ваша конфигурация с
proxy_cache
на кэш-сервере (порт 1652) позаботится о кэшировании только тогда, когда ответ модифицируется и удовлетворяет условиям кэширования.
Примеры использования ваших директив
-
Ваша конфигурация на Caching Server:
location / { proxy_pass http://my-django-rest-api/; ... proxy_cache my_zone; proxy_cache_valid 200 302 36M; ... }
Здесь вы определяете, что ответы со статусом 200 и 302 будут кэшироваться на 36 минут. Если ваши запросы не соответствуют данным статусам, они не будут кэшироваться.
-
Конфигурация Origin Server:
location / { try_files $uri $uri/ =404; }
Эта конфигурация не добавляет никаких указаний на кэширование, кроме
Cache-Control
, который не будет учитывать кэш на стороне proxy.
Решение вашей проблемы
Чтобы исправить ситуацию и получить кэширование по запросу на ваш NGINX Caching Server, выполните следующие шаги:
-
Добавьте заголовок
Cache-Control
на кэш-сервере: Так как это управляет тем, как кэш считывает ответы, добавьте этот заголовок в кэш-сервере для всех ответов, которые вы хотите кэшировать. -
Исправьте директивы: Убедитесь, что в вашем Caching Server установлены соответствующие
proxy_cache_valid
для всех типов ответов, которые вы ожидаете кэшировать:proxy_cache_valid 200 302 36m; proxy_cache_valid 404 10m;
-
Используйте статус 200: Убедитесь, что ваши запросы к серверу Django возвращают статус 200, чтобы они могли быть закэшированы.
-
Проверяйте заголовки в Postman: Обратите внимание на заголовки, которые возвращает ваш кэш-сервер. Сравните заголовок
X-Proxy-Cache
после запроса. Если он возвращает "MISS", это означает, что для запрашиваемого ресурса нет кэша.
В результате, добавление соответствующих заголовков и правильное управление статусами ответов должны помочь вам организовать кэширование так, как вы хотите.