Nginx не кешує дані


16

Я маю REST API за проксі-сервером nginx. Проксінг працює чудово, проте я не в змозі кешувати відповіді. Будь-яка допомога буде дуже вдячна:

Конфігурація Nginx:

worker_processes  10;
error_log  logs/error.log;
error_log  logs/error.log  notice;
error_log  logs/error.log  info;

pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
        proxy_cache_path /path/to/cache/dir keys_zone=one:60m;
        proxy_cache_methods GET HEAD POST;

     upstream backend {
        server server1 backup;
        server server2 weight=5;
    }
    access_log  logs/access.log;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
        listen       7076;
        server_name  localhost;
        #charset koi8-r;
        access_log  logs/host.access.log;

        location / {
            add_header 'Access-Control-Allow-Origin' *;
            add_header 'Access-Control-Allow-Credentials' 'true';
            add_header 'Access-Control-Allow-Headers' 'Content-Type,Accept';
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';

            proxy_cache one;
            proxy_cache_key $host$uri$is_args$args;

            add_header X-Proxy-Cache $upstream_cache_status;

            proxy_ignore_headers X-Accel-Expires Expires Cache-Control Set-Cookie;
            proxy_ignore_headers Set-Cookie;
            proxy_ignore_headers Cache-Control;

            proxy_hide_header Cache-Control;
            proxy_hide_header Set-Cookie;
            proxy_pass http://backend;
        }
    }
}

Незалежно від того, що я намагався, Proxy-кеш завжди повертається як МІС:

Заголовки запиту:

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Host:nginxserver:portnumber
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36

Заголовки відповіді:

Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:Content-Type,Accept
Access-Control-Allow-Methods:GET, POST, OPTIONS
Access-Control-Allow-Origin:*
Connection:keep-alive
Content-Type:text/plain;charset=UTF-8
Date:Wed, 15 Oct 2014 16:30:18 GMT
Server:nginx/1.7.4
Transfer-Encoding:chunked
X-Proxy-Cache:MISS

Я підозрюю, що це щось із заголовками клієнта, але навіть якщо я зателефонував за допомогою curl та перевірив заголовки, відповіді немає.

Спасибі заздалегідь


1
У заголовку запиту: Cache-Control:max-age=0... що означає "не кешувати цей запит".
Натан C

1
Чи є спосіб, щоб я ігнорував це в заголовку клієнта? Це не пояснює, чому він не працює і через curl ....
user2630270

@ user2630270 Яка початкова URL-адреса та спосіб запиту? Що таке проміжна відповідь?
Ксав'є Лукас

@XavierLucas методи для заголовків, наведених вище, GET, оскільки я зараз вирішую проблему з Chrome. Запит - це щось по лінії nginxserver: port / solr / asd / select? Q = *: *. Я не знаю, як отримати проміжну відповідь. Де я можу знайти інструкції з цього приводу?
користувач2630270

Якщо я потрапляю на додаток безпосередньо, не переходячи через nginx, з точно таким же запитом я отримую такі заголовки відповідей: Content-Type: text / plain; charset = UTF-8 Transfer-Encoding: chunked
user2630270

Відповіді:


45

Ви не сказали nginx, скільки часу відповідь є дійсною і її потрібно подавати з кешу.

Це повинно бути визначено proxy_cache_validдирективою.

proxy_cache one;
proxy_cache_key $host$uri$is_args$args;
proxy_cache_valid 200 10m;

Але це не працюватиме для запитів POST, оскільки у вас немає ключа кешу, який відрізняється від запиту POST на іншого за тією ж URL-адресою, якщо вони не мають однакового вмісту.

Тому вам потрібно буде налаштувати кеш-ключ $host$request_uri|$request_body. Вам доведеться стежити за розміром ( proxy_cache_pathпараметром max_size) кешу та буфером відповіді проксі, proxy_buffer_sizeщоб він відповідав вашим потребам.


Приємно, дякую людино! Це спрацювало. Бажайте, щоб це було зафіксовано десь дещо більш чітко.
користувач2630270

Якщо ця директива не встановлена, будь-яка відповідь буде кешована. Але це перекреслюється заголовком X-Accel-Expire, Cache-Control або Expire програми. Принаймні, Set-Cookie і Vary могли уникнути кешу. Ці факти викриваються в док. Я створив простий сценарій для тестування, оскільки мій фреймворк, Laravel, завжди надсилає вищезазначені заголовки.
Віктор Агілар

Це працював Сяв'є Лукас. Спасибі. Я також додав значення кеш-різниці часу для різних HTTP-кодів: proxy_cache_valid 200 302 10m; ////// proxy_cache_valid 404 1м;
Деунц

16

Від: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_valid

Синтаксис: proxy_cache_valid [код ...] час;

...

Параметри кешування також можна встановити безпосередньо в заголовку відповіді. Це має більш високий пріоритет, ніж встановлення часу кешування за допомогою директиви.

  • Поле заголовка "X-Accel-Expires" задає час кешування відповіді в секундах. Нульове значення вимикає кешування відповіді. Якщо значення починається з префіксу @, воно встановлює абсолютний час у секундах після епохи, до якого відповідь може кешуватися.
  • Якщо заголовок не містить поля "X-Accel-Expires", параметри кешування можуть бути встановлені в полях заголовка "Expires" або
    "Cache-Control".
  • Якщо заголовок містить поле «Set-Cookie» , така відповідь не буде кешована.
  • Якщо заголовок містить поле "Vary" зі спеціальним значенням "*", така відповідь не буде кешована (1.7.7). Якщо заголовок містить
    поле «Варіант» з іншим значенням, така відповідь буде кешована
    з урахуванням відповідних полів заголовка запиту (1.7.7).

Обробку одного або декількох цих полів заголовка відповіді можна відключити за допомогою директиви proxy_ignore_headers .

Більшість веб-додатків встановлюють Set-Cookieзаголовок, тому відповідь не буде кешована. Щоб виправити це, скористайтеся цією директивою:

proxy_ignore_headers Set-Cookie;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.