NGINX кэширующий сервер с обратным прокси работает не так, как ожидалось

Вопрос или проблема

Я настроил обратный прокси-сервер 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). Основные моменты, которые нужно учитывать:

  1. Директивы add_header и их влияние: Заголовки, добавленные с помощью add_header, будут отправляться клиенту, но это не влияет на кэширование ответов. Кэширование контролируется директивами proxy_cache, proxy_cache_valid и другими кэширующими настройками.

  2. Важность статусов: Директивы proxy_cache_valid используются для определения того, какие коды состояния HTTP разрешают кэширование. Если ваш сервер возвращает статус ответа, который не совпадает с определениями в proxy_cache_valid, кэширование не произойдет.

  3. Кэширование в 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, выполните следующие шаги:

  1. Добавьте заголовок Cache-Control на кэш-сервере: Так как это управляет тем, как кэш считывает ответы, добавьте этот заголовок в кэш-сервере для всех ответов, которые вы хотите кэшировать.

  2. Исправьте директивы: Убедитесь, что в вашем Caching Server установлены соответствующие proxy_cache_valid для всех типов ответов, которые вы ожидаете кэшировать:

    proxy_cache_valid 200 302 36m;
    proxy_cache_valid 404 10m;
  3. Используйте статус 200: Убедитесь, что ваши запросы к серверу Django возвращают статус 200, чтобы они могли быть закэшированы.

  4. Проверяйте заголовки в Postman: Обратите внимание на заголовки, которые возвращает ваш кэш-сервер. Сравните заголовок X-Proxy-Cache после запроса. Если он возвращает "MISS", это означает, что для запрашиваемого ресурса нет кэша.

В результате, добавление соответствующих заголовков и правильное управление статусами ответов должны помочь вам организовать кэширование так, как вы хотите.

Оцените материал
Добавить комментарий

Капча загружается...