Nginx não está armazenando em cache os dados


15

Eu tenho uma API REST por trás de um proxy nginx. O proxy funciona bem, no entanto, não consigo armazenar em cache nenhuma resposta. Qualquer ajuda seria muito apreciada:

Configuração do 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;
        }
    }
}

Não importa o que eu tentei, o Proxy-Cache sempre volta como uma MISS:

Os cabeçalhos da solicitação são:

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

Os cabeçalhos de resposta são:

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

Minha suspeita é que é algo com os cabeçalhos do cliente, mas mesmo se eu emitir a chamada via curl e verificar os cabeçalhos, não há resposta.

desde já, obrigado


1
No cabeçalho da solicitação: Cache-Control:max-age=0... isso implica em "não armazenar em cache esta solicitação".
— Nathan C

Existe uma maneira de eu ignorar isso no cabeçalho do cliente? Isso não explica por que ele não funciona através de onda quer embora ....
— user2630270

@ user2630270 Qual é o URL e o método de solicitação inicial? Qual é a resposta intermediária?
— Xavier Lucas

@XavierLucas, os métodos para os cabeçalhos acima são GET, pois agora estou solucionando o problema do Chrome. A solicitação é algo do tipo nginxserver: port / solr / asd / select? Q = *: *. Não sei como capturar resposta intermediária. Onde posso encontrar instruções sobre isso?
— user2630270

Se eu acessar o aplicativo diretamente sem passar pelo nginx, com a mesma consulta, obtenho os seguintes cabeçalhos de resposta: Tipo de conteúdo: texto / sem formatação; charset = UTF-8 Transfer-Encoding: chunked
— user2630270

Respostas:


44

Você não disse ao nginx por quanto tempo a resposta é válida e deve ser veiculada no cache.

Isso deve ser especificado com a proxy_cache_validdiretiva.

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

Porém, isso não funcionará para solicitações POST, porque você não possui uma chave de cache que difere de uma solicitação POST para outra na mesma URL se elas não tiverem o mesmo conteúdo.

Portanto, você precisará ajustar a chave de cache para $host$request_uri|$request_body. Você precisará monitorar o tamanho do cache ( proxy_cache_pathparâmetro max_size) e o buffer de resposta do proxy proxy_buffer_sizepara que ele se adapte às suas necessidades.


Bom, valeu cara! Funcionou. Gostaria que fosse documentado em algum lugar um pouco mais explicitamente.
— user2630270

Se essa diretiva não estiver definida, qualquer resposta será armazenada em cache. Mas esse é substituído pelo cabeçalho X-Accel-Expire, Cache-Control ou Expir do aplicativo. Pelo menos, Set-Cookie e Vary poderiam evitar o cache. Esses fatos estão expostos no documento. Criei um script simples para testar porque meu framework, Laravel, sempre envia os cabeçalhos acima.
— Victor Aguilar

15

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

Sintaxe: proxy_cache_valid [code ...] time;

...

Os parâmetros de armazenamento em cache também podem ser definidos diretamente no cabeçalho da resposta. Isso tem prioridade mais alta do que a configuração do tempo de armazenamento em cache usando a diretiva.

  • O campo de cabeçalho “X-Accel-Expires” define o tempo de cache de uma resposta em segundos. O valor zero desativa o armazenamento em cache para uma resposta. Se o valor começar com o prefixo @, ele definirá um tempo absoluto em segundos desde a Epoch, até o qual a resposta pode ser armazenada em cache.
  • Se o cabeçalho não incluir o campo "X-Accel-Expira", os parâmetros de armazenamento em cache podem ser definidos nos campos de cabeçalho "Expira" ou
    "Controle de cache".
  • Se o cabeçalho incluir o campo "Set-Cookie" , essa resposta não será armazenada em cache.
  • Se o cabeçalho incluir o campo "Variar" com o valor especial "*", essa resposta não será armazenada em cache (1.7.7). Se o cabeçalho incluir
    o campo "Variar" com outro valor, essa resposta será armazenada
    em cache, levando em consideração os campos correspondentes do cabeçalho da solicitação (1.7.7).

O processamento de um ou mais desses campos de cabeçalho de resposta pode ser desativado usando a diretiva proxy_ignore_headers .

A maioria dos aplicativos Web define o Set-Cookiecabeçalho, portanto, uma resposta não será armazenada em cache. Para corrigir isso, use esta diretiva:

proxy_ignore_headers Set-Cookie;
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.