Nginx no almacena datos en caché

15

Tengo una API REST detrás de un proxy nginx. El proxy funciona bien, sin embargo, no puedo almacenar en caché ninguna respuesta. Cualquier ayuda sería muy apreciada:

Nginx config:

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

No importa lo que haya intentado, Proxy-Cache siempre regresa como MISS:

Los encabezados de solicitud son:

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

Los encabezados de respuesta son:

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

Mi sospecha es que es algo con los encabezados de los clientes, pero incluso si emito la llamada a través de curl y reviso los encabezados, no hay respuesta.

Gracias por adelantado

usuario2630270
fuente
1
En el encabezado de la solicitud: Cache-Control:max-age=0... eso implica "no almacenar en caché esta solicitud".
Nathan C
¿Hay alguna manera de ignorar eso en el encabezado del cliente? Sin embargo, esto no explica por qué tampoco funciona a través de curl ...
user2630270
@ user2630270 ¿Cuál es la URL y el método de la solicitud inicial? ¿Cuál es la respuesta intermedia?
Xavier Lucas
@XavierLucas los métodos para los encabezados anteriores son GET ya que ahora estoy solucionando el problema Chrome. La solicitud es algo similar a nginxserver: port / solr / asd / select? Q = *: *. No sé cómo capturar la respuesta intermedia. ¿Dónde puedo encontrar instrucciones sobre esto?
user2630270
Si llego a la aplicación directamente sin pasar por nginx, con la misma consulta obtengo los siguientes encabezados de respuesta: Content-Type: text / plain; charset = UTF-8 Transfer-Encoding: chunked
user2630270

Respuestas:

44

No le dijo a nginx por cuánto tiempo la respuesta es válida y debe ser atendida desde la memoria caché.

Esto debe especificarse con la proxy_cache_validdirectiva.

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

Pero esto no funcionará para las solicitudes POST porque no tiene una clave de caché que difiera de una solicitud POST a otra en la misma URL si no tienen el mismo contenido.

Por lo tanto, deberá ajustar la clave de caché $host$request_uri|$request_body. Tendrá que controlar el tamaño de la caché ( proxy_cache_pathparámetro max_size) y el búfer de respuesta proxy proxy_buffer_sizepara que se adapte a sus necesidades.

Xavier Lucas
fuente
Bien, gracias hombre! Funcionó. Ojalá estuviera documentado en algún lugar un poco más explícitamente.
user2630270
Si no se establece esta directiva, se almacenará en caché cualquier respuesta. Pero el encabezado X-Accel-Expire, Cache-Control o Expire de la aplicación reemplaza al primero. Al menos, Set-Cookie y Vary podrían evitar el caché. Estos hechos están expuestos en el documento. Creé un script simple para probar porque mi framework, Laravel, siempre envía los encabezados anteriores.
Victor Aguilar
15

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

Sintaxis: proxy_cache_valid [code ...] time;

...

Los parámetros de almacenamiento en caché también se pueden establecer directamente en el encabezado de respuesta. Esto tiene mayor prioridad que la configuración del tiempo de almacenamiento en caché utilizando la directiva.

  • El campo de encabezado "X-Accel-Expires" establece el tiempo de almacenamiento en caché de una respuesta en segundos. El valor cero deshabilita el almacenamiento en caché para una respuesta. Si el valor comienza con el prefijo @, establece un tiempo absoluto en segundos desde Epoch, hasta el cual se puede almacenar en caché la respuesta.
  • Si el encabezado no incluye el campo "X-Accel-Expires", los parámetros de almacenamiento en caché se pueden establecer en los campos de encabezado "Expires" o
    "Cache-Control".
  • Si el encabezado incluye el campo "Configurar cookie" , dicha respuesta no se almacenará en caché.
  • Si el encabezado incluye el campo "Variar" con el valor especial "*", dicha respuesta no se almacenará en caché (1.7.7). Si el encabezado incluye
    el campo "Variar" con otro valor, dicha respuesta se almacenará
    en caché teniendo en cuenta los campos de encabezado de solicitud correspondientes (1.7.7).

El procesamiento de uno o más de estos campos de encabezado de respuesta puede deshabilitarse utilizando la directiva proxy_ignore_headers .

La mayoría de las aplicaciones web establecen Set-Cookieencabezado, por lo que no se almacenará en caché una respuesta. Para arreglar eso, use esta directiva:

proxy_ignore_headers Set-Cookie;
Hieu
fuente