Nginx nie buforuje danych

16

Mam interfejs API REST za proxy Nginx. Serwer proxy działa dobrze, ale nie jestem w stanie buforować żadnych odpowiedzi. Każda pomoc będzie mile widziana:

Konfiguracja 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;
        }
    }
}

Bez względu na to, czego próbowałem, pamięć podręczna proxy zawsze wraca jako MISS:

Nagłówki żądania to:

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

Nagłówki odpowiedzi to:

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

Podejrzewam, że jest to coś z nagłówkami klienta, ale nawet jeśli wydam połączenie za pomocą curl i sprawdzę nagłówki, nie ma odpowiedzi.

Z góry dziękuję

użytkownik2630270
źródło
1
W nagłówku żądania: Cache-Control:max-age=0... oznacza to, że „nie buforuj tego żądania”.
Nathan C
1
Czy istnieje sposób, aby zignorować to w nagłówku klienta? Nie tłumaczy to jednak, dlaczego nie działa przez zwijanie ...
user2630270
@ user2630270 Jaki jest początkowy adres URL żądania i metoda? Jaka jest odpowiedź pośrednia?
Xavier Lucas
@XavierLucas metody dla powyższych nagłówków są GET, ponieważ teraz rozwiązuję problem z Chrome. Żądanie jest podobne do polecenia nginxserver: port / solr / asd / select? Q = *: *. Nie wiem, jak uchwycić odpowiedź pośrednią. Gdzie mogę znaleźć instrukcje na ten temat?
user2630270,
Jeśli bezpośrednio uruchomię aplikację bez przechodzenia przez nginx, z dokładnie tym samym zapytaniem otrzymam następujące nagłówki odpowiedzi: Content-Type: text / plain; charset = UTF-8 Transfer-Encoding:
chunked

Odpowiedzi:

45

Nie powiedziałeś nginx, przez ile czasu odpowiedź jest ważna i musisz ją podać z pamięci podręcznej.

Musi to zostać określone w proxy_cache_validdyrektywie.

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

Ale to nie zadziała dla żądań POST, ponieważ nie masz klucza pamięci podręcznej, który różni się od żądania POST do innego pod tym samym adresem URL, jeśli nie mają tej samej zawartości.

Musisz więc dostosować klucz pamięci podręcznej do $host$request_uri|$request_body. Będziesz musiał monitorować rozmiar pamięci podręcznej ( proxy_cache_pathparametr max_size) i bufor odpowiedzi proxy, proxy_buffer_sizeaby dopasować go do swoich potrzeb.

Xavier Lucas
źródło
Fajnie, dzięki stary! Zadziałało. Chciałbym, żeby zostało to udokumentowane gdzieś bardziej jednoznacznie.
user2630270,
Jeśli ta dyrektywa nie zostanie ustawiona, każda odpowiedź zostanie zapisana w pamięci podręcznej. Ale ten jest zastępowany przez nagłówek X-Accel-Expire, Cache-Control lub Expire aplikacji. Przynajmniej Set-Cookie i Vary mogą uniknąć bufora. Te fakty są ujawnione w dokumencie. Stworzyłem prosty skrypt do przetestowania, ponieważ mój framework, Laravel, zawsze wysyła powyższe nagłówki.
Victor Aguilar,
To działało Xiavier Lucas. Dzięki. Dodałem także różnicę czasu pamięci podręcznej dla różnych kodów HTTP: proxy_cache_valid 200 302 10m; ////// proxy_cache_valid 404 1m;
Deunz
16

Od: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_valid

Składnia: proxy_cache_valid [kod ...] czas;

...

Parametry buforowania można również ustawić bezpośrednio w nagłówku odpowiedzi. Ma to wyższy priorytet niż ustawianie czasu buforowania przy użyciu dyrektywy.

  • Pole nagłówka „X-Accel-Expires” określa czas buforowania odpowiedzi w sekundach. Wartość zero wyłącza buforowanie odpowiedzi. Jeśli wartość zaczyna się od przedrostka @, ustawia bezwzględny czas w sekundach od Epoki, do którego można buforować odpowiedź.
  • Jeśli nagłówek nie zawiera pola „X-Accel-Expires”, parametry buforowania można ustawić w polach nagłówka „Expires” lub
    „Cache-Control”.
  • Jeśli nagłówek zawiera pole „Set-Cookie” , taka odpowiedź nie będzie buforowana.
  • Jeśli nagłówek zawiera pole „Zmienna” ze specjalną wartością „*”, taka odpowiedź nie będzie buforowana (1.7.7). Jeśli nagłówek zawiera
    pole „Zmienna” o innej wartości, taka odpowiedź zostanie zbuforowana
    z uwzględnieniem odpowiednich pól nagłówka żądania (1.7.7).

Przetwarzanie jednego lub więcej pól nagłówka odpowiedzi można wyłączyć za pomocą dyrektywy proxy_ignore_headers .

Większość aplikacji internetowych ustawia Set-Cookienagłówek, więc odpowiedź nie będzie buforowana. Aby to naprawić, użyj tej dyrektywy:

proxy_ignore_headers Set-Cookie;
Cześć
źródło