Como configurar o Nginx como um proxy reverso de cache?

143

Ouvi recentemente que o Nginx adicionou cache ao seu recurso de proxy reverso. Olhei em volta, mas não consegui encontrar muita informação sobre isso.

Quero configurar o Nginx como um proxy reverso de armazenamento em cache na frente do Apache / Django: ter solicitações de proxy do Nginx para algumas (mas não todas) páginas dinâmicas no Apache, armazenar em cache as páginas geradas e servir solicitações subsequentes para essas páginas do cache.

Idealmente, eu gostaria de invalidar o cache de duas maneiras:

  1. Defina uma data de validade no item em cache
  2. Para invalidar explicitamente o item em cache. Por exemplo, se meu back-end do Django atualizou certos dados, eu gostaria de dizer ao Nginx para invalidar o cache das páginas afetadas

É possível configurar o Nginx para fazer isso? Quão?

Continuação
fonte
Não testado, mas em gumroad.com/l/ngx_purge : "ngx_purge é um módulo Lua puro para o Nginx que permite ao usuário limpar objetos do cache do nginx.".
Jaime Hablutzel

Respostas:

97

Não acho que exista uma maneira de invalidar explicitamente itens em cache, mas aqui está um exemplo de como fazer o resto. Atualização: Como mencionado por Piotr em outra resposta, existe um módulo de limpeza de cache que você pode usar. Você também pode forçar uma atualização de um item em cache usando proxy_cache_bypass do nginx - consulte a resposta de Cherian para obter mais informações.

Nesta configuração, os itens que não são armazenados em cache serão recuperados do example.net e armazenados. As versões em cache serão veiculadas para futuros clientes até que não sejam mais válidas (60 minutos).

Seus cabeçalhos HTTP de controle de cache e expiram serão respeitados; portanto, se você desejar definir explicitamente uma data de validade, poderá fazê-lo definindo os cabeçalhos corretos no que você estiver utilizando como proxy.

Há muitos parâmetros que você pode ajustar - consulte a documentação do módulo nginx Proxy para obter mais informações sobre tudo isso, incluindo detalhes sobre o significado das diferentes configurações / parâmetros: http://nginx.org/r/proxy_cache_path

http {
  proxy_cache_path  /var/www/cache levels=1:2 keys_zone=my-cache:8m max_size=1000m inactive=600m;
  proxy_temp_path /var/www/cache/tmp; 


  server {
    location / {
      proxy_pass http://example.net;
      proxy_cache my-cache;
      proxy_cache_valid  200 302  60m;
      proxy_cache_valid  404      1m;
    }
  }
}
Casey
fonte
7
Este é um primeiro passo razoável para novos aplicativos que não possuem 20k / req / s.
5
@ Barry, qual deve ser o segundo passo?
Jürgen Paul
42
@Legit - eu não sei, mas, tradicionalmente, o último passo é :-) "Lucro"
Stephen C
Infelizmente, ele não funciona com o nginx 1.11. Como a última atualização ocorreu há cerca de 3 anos, parece que isso não é mais a solução.
izogfif
O que inactive=600msignifica : Não inactivedeveria ser tempo? `[inactive=time]
NeverEndingQueue
47

Você pode invalidar especificamente páginas em cache por meio de

proxy_cache_bypass       

Digamos que você queira armazenar em cache uma página, configure o cache dessa maneira

location = /pageid {
  proxy_pass http://localhost:82;
  proxy_set_header   Host             $host;
  proxy_set_header   X-Real-IP        $remote_addr;
  proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
  proxy_ignore_headers Set-Cookie; 
  proxy_ignore_headers Cache-Control; 
  proxy_cache_bypass        $http_secret_header;
  add_header X-Cache-Status $upstream_cache_status;
}

Agora, quando você deseja invalidar essa página e armazenar em cache novamente

Faça uma chamada secreta com o cabeçalho

curl "www.site.com/pageid" -s -I -H "secret_header:true" 

Ele será invalidado e armazenado em cache.

Funciona a partir do nginx 0.7.

Como um bônus adicional, add_header X-Cache-Statuspode ser usado para verificar se a página é do cache ou não.

Cherian
fonte
Isso só pode atualizar páginas em cache quando a nova página também é armazenável em cache. Se você removeu uma página (404 ou outros erros agora são exibidos pelo back-end), a página agora envia um cabeçalho Set-Cookie ou "Content-Control: private", o conteúdo em cache não será "invalidado".
RBU
36

Eu sugiro que você experimente o Varnish . O verniz foi projetado especificamente como um cache de proxy reverso. Ele respeitará todos os cabeçalhos de controle de cache que você enviar do servidor de origem, o que satisfaz sua primeira solicitação.

Para sua segunda solicitação, invalidação explícita. Minha forte recomendação é alterar o nome do URL do recurso que você deseja invalidar, renomeando o arquivo ou usando alguma forma de buster de cache de string de consulta. O Varnish possui uma PURGEoperação que removerá o recurso do cache do Varnish, mas não fornecerá controle sobre outros caches entre você e o usuário. Como você disse que deseja limpar explicitamente um recurso, os cabeçalhos de controle http padrão não o ajudarão. Nesse caso, a maneira mais infalível de anular o armazenamento em cache de um recurso é renomeá-lo.

Dave Cheney
fonte
Você poderia explicar o que você quis dizer com "renomear o arquivo ou usar alguma forma de buster de cache de string de consulta"? Não sei se entendi por que não é uma boa ideia usar uma operação como PURGE.
continuação
5
+1 para verniz. É sempre muito melhor usar as ferramentas certas para o trabalho.
Tom O'Connor
4
@ abaixo: Quase não há esperança de tocar o verniz nas arenas de desempenho e versatilidade. Isso é apoiado por um dos principais desenvolvedores de kernel do FreeBSD e por uma equipe dedicada sediada na Europa. O verniz está em produção no twitter, heroku e muitos mais.
2
O exemplo mais simples de um cache-buster é anexar um número de versão em uma string de consulta a um recurso estático, para que style.css se torne style.css? 123. Quando você deseja enviar por push uma nova versão do arquivo, altere o URL do recurso para style.css? 124 e agora os caches o buscarão como um recurso totalmente novo a ser armazenado em cache separadamente. O Apache exibirá o arquivo style.css com qualquer sequência de consultas anexada, portanto, nenhuma alteração no arquivo real será necessária.
Ch20
3
Se possível, é melhor colocar o buster de cache no próprio nome do arquivo, como style.v123.cssporque alguns caches não armazenam em cache solicitações que tenham uma sequência de consultas.
Noah McIlraith
8

Para invalidar páginas selecionadas, você pode usar o patch "cache_purge" para o nginx-0.8.x, que faz exatamente o que você deseja;)

Está disponível aqui .


fonte
8

A maioria das ferramentas de cache (Citrix) permite que uma atualização forçada (Ctrl + r) repovoe uma página em cache.

Aqui está um truque que encontrei para fazer algo semelhante no nginx.

server  {
        # Other settings
        proxy_pass_header       Set-Cookie; # I want to cache logged-in users
        proxy_ignore_headers    X-Accel-Redirect;
        proxy_ignore_headers    X-Accel-Expires Expires Cache-Control;
        if ($http_cache_control ~ "max-age=0") {set $eac 1;}
        proxy_cache_bypass $eac;
}

Isso pressupõe que, quando você pressiona Ctrl + r no navegador, o cabeçalho Cache-Control possui max-age = 0 em sua solicitação. Sei que o Chrome faz isso, mas não tentei em outros navegadores. Adicionar mais campos de cabeçalho pode ser fácil, apenas adicionando mais instruções if que definem a $eacvariável como 1.

Randy Wallace
fonte
4

Acredito que NginxHttpProxyModule é capaz de receber solicitações http. Procure as diretrizes começando com:

proxy_cache

Sim, é possível controlar o comportamento do cache por meio de diretivas como:

proxy_cache_valid
Taras Chuhay
fonte
3

Com base no fato de que você não consegue encontrar documentos, eu ficaria um pouco cauteloso ao confiar nele na produção. Você já considerou o verniz? É o meu "nginx de proxies reversos", pequeno, leve, fazendo um trabalho e fazendo-o bem.

mulher
fonte
A documentação está aqui: wiki.nginx.org/NginxHttpProxyModule#proxy_cache
rmalayter
2

Se você usar eTags no seu aplicativo e colocar o nginx na frente dele, ele cuidará da expiração, pois se o eTag mudar, o cache será invalidado.

Martin Murphy
fonte
Realmente? Parece que o ngnix corresponde ao etag e nunca fala com o aplicativo para descobrir se existe um etag atualizado.
John Naegle
2

Você pode controlar a expiração do cache do Nginx com várias diretivas / parâmetros:

  • proxy_cache_valid 200 302 10m;
  • adicionando um dos cabeçalhos HTTP abaixo (a prioridade é importante - confira minha postagem no blog ):
    • Expires
    • Cache-Control
    • X-Accel-Expires
  • o inactiveparâmetro na proxy_cache_pathdiretiva:

    proxy_cache_path /data/nginx/cache keys_zone=one:10m inactive=60m;

Eu recomendo minha postagem no blog se você quiser saber mais sobre o cache do Nginx.

O tópico de remoção é realmente interessante, pois esse recurso existe apenas no Nginx Plus (edição comercial do Nginx). Eu realmente gosto da resposta @ Randy-Wallace. Mas também existem outras possibilidades, como o módulo ngx_cache_purge .

A coisa mais simples que você pode fazer é remover o arquivo em cache manualmente:

  • gere sua chave de hash:

    echo -n ‘httpczerasz.com/time.php’ | md5sum
    
  • remova o arquivo do sistema de arquivos:

    rm /data/nginx/cache/1/27/2bba799df783554d8402137ca199a271
    
czerasz
fonte
1

Para futuros visitantes: enquanto isso, o proxy reverso nginx possui armazenamento em cache integrado e os documentos estão disponíveis em:

Sintaxe: zona proxy_cache | fora;

Padrão: proxy_cache desativado;

Contexto: http, servidor, localização

Define uma zona de memória compartilhada usada para armazenamento em cache. A mesma zona pode ser usada em vários lugares. O valor do parâmetro pode conter variáveis ​​(1.7.9). O parâmetro off desativa o cache herdado do nível de configuração anterior.

Tarik Huclaslun
fonte
Oi Tarik, a pergunta era muito específica sobre o que precisa ser alcançado, e está um pouco além do 'apenas ativar cache'.
asdmin
0
níveis fastcgi_cache_path / opt / nginx-cache = 2: 2 keys_zone = img: 50m;

    location / img / {
        fastcgi_pass $ back-end;
        inclua fcgi_params;
        fastcgi_intercept_errors desativado;   
        fastcgi_cache_key $ server_addr $ request_uri;       
        fastcgi_cache img;
        fastcgi_cache_valid qualquer 1m;
        fastcgi_hide_header Set-Cookie;
    }

Isso cria cache para / img / location. Está em / opt / nginx-cache. Os objetos são armazenados em cache por 1 minuto.

Você pode escrever códigos de resposta diferentes em vez de qualquer.

Agora você não pode invalidar o cache das páginas selecionadas. Talvez em 0.8.x seja possível.

lexsys
fonte
A pergunta original era sobre o uso do nginx na frente do Apache, não na frente do aplicativo fastcgi tratado pelo nginx.
Graham Dumpleton
0

Existe um plugin nginx chamado ncache, que afirma ser "um sistema de cache da web baseado no servidor da web nginx. Mais rápido e mais eficiente que o squid".

sajal
fonte