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

user2630270
fonte
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.

Xavier Lucas
fonte
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;
Hieu
fonte