Como Fazer Cache de Conteúdo no NGINX

NGINX sendo um servidor web de código aberto consolidado e de alto desempenho que acelera a entrega de conteúdo e aplicativos, aprimora a segurança e melhora a escalabilidade. Um dos casos de uso mais comuns do Nginx é o Cache de Conteúdo, que é a maneira mais eficaz de aumentar o desempenho de um site.

Leia também: 10 Principais Ferramentas de Cache de Código Aberto para Linux

Você pode usar o NGINX para acelerar servidores de origem locais configurando-o para armazenar em cache respostas de servidores upstream e também para criar servidores de borda para redes de entrega de conteúdo (CDNs). O NGINX alimenta algumas das maiores CDNs.

Ao ser configurado como um cache, o NGINX irá:

  • armazenar conteúdo estático e dinâmico.
  • melhorar o desempenho de conteúdo dinâmico com micro-cache.
  • servir conteúdo obsoleto enquanto revalida em segundo plano para melhor desempenho.
  • substituir ou definir cabeçalhos Cache-Control, e mais.

Neste artigo, você aprenderá como configurar o NGINX como um Cache de Conteúdo no Linux para fazer com que seus servidores web funcionem da maneira mais eficiente possível.

Pré-requisitos:

Você deve ter o NGINX instalado em seu servidor Linux, se não, siga estes guias para instalar o Nginx:

Cache de Conteúdo Estático no Nginx

O conteúdo estático é o conteúdo de um site que permanece o mesmo (não muda) em todas as páginas. Exemplos de conteúdo estático incluem arquivos como imagens, vídeos, documentos; arquivos CSS e arquivos JavaScript.

Se o seu site faz uso de muito conteúdo estático, então você pode otimizar seu desempenho habilitando o cache do lado do cliente, onde o navegador armazena cópias do conteúdo estático para acesso mais rápido.

A configuração de exemplo a seguir é uma boa opção, basta substituir www.example.com pelo URL do nome do seu site e fazer modificações em outros caminhos conforme necessário.

server {
    # substitute your web server's URL for www.example.com
    server_name www.example.com;
    root /var/www/example.com/htdocs;
    index index.php;

    access_log /var/log/nginx/example.com.access.log;
    error_log /var/log/nginx/example.com.error.log;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ .php$ {
        try_files $uri =404;
        include fastcgi_params;
        # substitute the socket, or address and port, of your WordPress server
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        #fastcgi_pass 127.0.0.1:9000;
 	}   

    location ~* .(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg
                  |jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid
                  |midi|wav|bmp|rtf)$ {
        expires max;
        log_not_found off;
        access_log off;
    }
}

Cache de Conteúdo Dinâmico no Nginx

O NGINX usa um cache persistente baseado em disco localizado em algum lugar no sistema de arquivos local. Portanto, comece criando o diretório de disco local para armazenar o conteúdo em cache.
# mkdir -p /var/cache/nginx

Em seguida, defina a propriedade apropriada no diretório de cache. Deve ser de propriedade do usuário NGINX (nginx) e do grupo (nginx) da seguinte forma.

# chown nginx:nginx /var/cache/nginx

Agora prossiga para ver como habilitar o conteúdo dinâmico no Nginx na seção abaixo.

Habilitando o Cache FastCGI no NGINX

O FastCGI (ou FCGI) é um protocolo amplamente utilizado para interagir com aplicativos interativos como o PHP em servidores web como o NGINX. É uma extensão do CGI (Interface Comum de Gateway).

A principal vantagem do FCGI é que ele gerencia múltiplas solicitações CGI em um único processo. Sem ele, o servidor web precisa abrir um novo processo (que precisa ser controlado, processar uma solicitação e ser fechado) para cada solicitação de cliente para um serviço.

Para processar scripts PHP em uma implantação de pilha LEMP, o NGINX usa o FPM (Gerenciador de Processos FastCGI) ou PHP-FPM, uma implementação alternativa popular do FastCGI PHP. Uma vez que o processo PHP-FPM está em execução, o NGINX é configurado para encaminhar solicitações para ele para processamento. Assim, o NGINX também pode ser configurado para armazenar em cache as respostas do servidor de aplicativos de backend PHP-FPM.

Sob o NGINX, o cache de conteúdo FastCGI é declarado usando uma diretiva chamada fastcgi_cache_path no contexto http{} de nível superior, dentro da estrutura de configuração do NGINX. Você também pode adicionar o fastcgi_cache_key que define uma chave (identificador de solicitação) para o cache.

Além disso, para ler o status do cache upstream, adicione a diretiva add_header X-Cache-Status dentro do contexto http{} – isso é útil para fins de depuração.

Supondo que o arquivo de configuração do bloco do servidor do seu site esteja localizado em /etc/nginx/conf.d/testapp.conf ou /etc/nginx/sites-available/testapp.conf (no Ubuntu e seus derivados), abra o arquivo para edição e adicione as seguintes linhas no topo do arquivo.

fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=CACHEZONE:10m; inactive=60m max_size=40m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
add_header X-Cache $upstream_cache_status;
Enable FastCGI Cache in NGINX

A diretiva fastcgi_cache_path especifica o número de parâmetros que são:

  • /var/cache/nginx – o caminho para o diretório do disco local para o cache.
  • levels – define os níveis hierárquicos de um cache, configurando uma hierarquia de diretórios de dois níveis embaixo de /var/cache/nginx.
  • keys_zone (nome:tamanho) – permite a criação de uma zona de memória compartilhada onde todas as chaves ativas e informações sobre os dados (meta) são armazenadas. Observe que armazenar as chaves na memória acelera o processo de verificação, facilitando para o NGINX determinar se é um MISS ou um HIT, sem verificar o status no disco.
  • inactive – especifica a quantidade de tempo após o qual os dados em cache que não são acessados durante o tempo especificado são excluídos do cache, independentemente de sua frescura. Um valor de 60m em nossa configuração de exemplo significa que os arquivos não acessados após 60 serão removidos do cache.
  • max_size – especifica o tamanho máximo do cache. Existem mais parâmetros que você pode usar aqui (leia a documentação do NGINX para mais informações).

As variáveis na diretiva fastcgi_cache_key são descritas abaixo.

O NGINX as utiliza para calcular a chave (identificador) de uma requisição. Importante, para enviar uma resposta em cache para o cliente, a requisição deve ter a mesma chave que uma resposta em cache.

  • $scheme – esquema da requisição, HTTP ou HTTPS.
  • $request_method – método da requisição, geralmente “GET” ou “POST”.
  • $host – isso pode ser o nome do host da linha de requisição, ou o nome do host do campo de cabeçalho de requisição “Host”, ou o nome do servidor que corresponde a uma requisição, na ordem de precedência.
  • $request_uri – significa o URI completo original da requisição (com argumentos).

Também, a variável $upstream_cache_status na diretiva add_header X-Cache-Status é calculada para cada requisição à qual o NGINX responde, seja um MISS (resposta não encontrada no cache, obtida do servidor de aplicação) ou um HIT (resposta servida do cache) ou qualquer um dos outros valores suportados.

Em seguida, dentro da diretiva location que encaminha as requisições PHP para o PHP-FPM, usa as diretivas fastcgi_cache para ativar o cache que você acabou de definir acima.

Também defina o tempo de cache para diferentes respostas usando a diretiva fastcgi_cache_valid como mostrado.

fastcgi_cache CACHEZONE;
fastcgi_cache_valid  60m;
Define Caching Zone and Time

Se apenas o tempo de armazenamento em cache for especificado, como no nosso caso, apenas as respostas 200, 301 e 302 são armazenadas em cache. Mas você também pode especificar as respostas explicitamente ou usar qualquer (para qualquer código de resposta):

fastcgi_cache CACHEZONE;
fastcgi_cache_valid 200  301 203 60m;
fastcgi_cache_valid 404 10m;
OR
fastcgi_cache CACHEZONE;
fastcgi_cache_valid  any 10m;

Otimizando o Desempenho do Cache FastCGI no Nginx

Para definir o número mínimo de vezes que uma solicitação com a mesma chave deve ser feita antes que a resposta seja armazenada em cache, inclua a diretiva fastcgi_cache_min_uses, seja no contexto http{}, server{} ou location{}.

fastcgi_cache_min_uses  3
Set Minimum Cache Usage

Para habilitar a revalidação de itens de cache expirados usando solicitações condicionais com os campos de cabeçalho “If-Modified-Since” e “If-None-Match“, adicione a diretiva fastcgi_cache_revalidate, dentro do contexto http{}, server{} ou location{}.

fastcgi_cache_revalidate on;
Set Cache Re-validation

Você também pode instruir o NGINX a entregar conteúdo em cache quando o servidor de origem ou o servidor FCGI estiver inativo, usando a diretiva proxy_cache_use_stale, dentro da diretiva de localização.

Esta configuração de exemplo significa que quando o NGINX recebe um erro, tempo esgotado e qualquer um dos erros especificados do servidor upstream e tem uma versão obsoleta do arquivo solicitado no conteúdo em cache, ele entrega o arquivo obsoleto.

proxy_cache_use_stale error timeout http_500;
Enable Serving of Stale Data

Outra diretiva útil para ajustar o desempenho do cache FCGI é fastcgi_cache_background_update, que funciona em conjunto com a diretiva proxy_cache_use_stale. Quando definido como “ligado”, instrui o NGINX a servir conteúdo obsoleto quando os clientes solicitam um arquivo que expirou ou está em processo de atualização a partir do servidor upstream.

fastcgi_cache_background_update on;
Enable Cache Background Update

O fastcgi_cache_lock também é útil para ajustar o desempenho do cache, pois, se vários clientes solicitarem o mesmo conteúdo que não está em cache, o NGINX encaminhará apenas a primeira solicitação para o servidor upstream, armazenará em cache a resposta e depois servirá as outras solicitações dos clientes a partir do cache.

fastcgi_cache_lock on;
Enable Cache Lock

Após fazer todas as alterações acima no arquivo de configuração do NGINX, salve e feche-o. Em seguida, verifique a estrutura da configuração quanto a erros de sintaxe antes de reiniciar o serviço NGINX.

# nginx -t
# systemctl restart nginx
Check and Start Nginx Service

Em seguida, teste se o cache está funcionando corretamente, tente acessar sua aplicação web ou site usando o seguinte comando curl (a primeira vez deve indicar um MISS, mas as solicitações subsequentes devem indicar um HIT, como mostrado na captura de tela).

# curl -I http://testapp.tecmint.com
Test FastCGI Cache

Aqui está outra captura de tela mostrando o NGINX servindo dados obsoletos.

Test Nginx Serving Stale Data

Adicionando Exceções para Ignorar o Cache

É possível definir condições sob as quais o NGINX não deve enviar respostas em cache para os clientes, utilizando a diretiva fastcgi_cache_bypass. E para instruir o NGINX a não armazenar em cache respostas do servidor upstream, utilize o fastcgi_no_cache.

Por exemplo, se deseja que solicitações POST e URLs com uma string de consulta sempre sejam direcionados para o PHP. Primeiramente, declare uma instrução if para definir a condição da seguinte forma.

set $skip_cache 0; 
if ($request_method = POST) { 
	set $skip_cache 1; 
} 

Em seguida, ative a exceção acima na diretiva location que encaminha solicitações PHP para o PHP-FPM, utilizando as diretivas fastcgi_cache_bypass e fastcgi_no_cache.

 
fastcgi_cache_bypass $skip_cache; 
fastcgi_no_cache $skip_cache;

Há muitas outras partes do seu site para as quais você pode não querer habilitar o cache de conteúdo. O seguinte é um exemplo de configuração do NGINX para melhorar o desempenho de um site WordPress, fornecido no blog nginx.com.

Para utilizá-lo, faça alterações (como o domínio, caminhos, nomes de arquivos, etc.) para refletir o que existe em seu ambiente.

fastcgi_cache_path /var/run/NGINX-cache levels=1:2 keys_zone=WORDPRESS:100m inactive=60m; 
fastcgi_cache_key "$scheme$request_method$host$request_uri"; 
server { 
	server_name example.com www.example.com; 
	root /var/www/example.com; 
	index index.php; 
	access_log /var/log/NGINX/example.com.access.log; 
	error_log /var/log/NGINX/example.com.error.log; 
	set $skip_cache 0; 
	# POST requests and URLs with a query string should always go to PHP 	
	if ($request_method = POST) { 
		set $skip_cache 1; 
	} 
	if ($query_string != "") {
		set $skip_cache 1; 
	} 
	# Don't cache URIs containing the following segments 
	if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php |sitemap(_index)?.xml") { 
		set $skip_cache 1; 
	} 
	# Don't use the cache for logged-in users or recent commenters 
	if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass |wordpress_no_cache|wordpress_logged_in") {
		set $skip_cache 1; 
	} 
	location / { 
		try_files $uri $uri/ /index.php?$args; 
	} 
	location ~ .php$ { 
		try_files $uri /index.php; 
		include fastcgi_params; 
		fastcgi_pass unix:/var/run/php5-fpm.sock; 
		fastcgi_cache_bypass $skip_cache; 
		fastcgi_no_cache $skip_cache; 
		fastcgi_cache WORDPRESS; 
		fastcgi_cache_valid 60m; 
	} 
	location ~ /purge(/.*) {
		fastcgi_cache_purge WORDPRESS "$scheme$request_method$host$1"; 
	} 
	location ~* ^.+.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg|jpeg |gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi |wav|bmp|rtf)$ { 
		access_log off; 
		log_not_found off; 
		expires max; 
	} 
	location = /robots.txt { 
		access_log off; 
		log_not_found off; 
	}
	location ~ /. { 
		deny all; 
		access_log off; 
		log_not_found off; 
	} 
}

Habilitando o Cache de Proxy no NGINX

NGINX também suporta o cache de respostas de outros servidores proxy (definidos pela diretiva proxy_pass). Para este caso de teste, estamos utilizando o NGINX como um proxy reverso para uma aplicação web Node.js, então habilitaremos o NGINX como um cache para a aplicação Node.js. Todas as diretivas de configuração utilizadas aqui têm significados semelhantes às diretivas FastCGI na seção anterior, então não as explicaremos novamente.

Para habilitar o armazenamento em cache de respostas de um servidor proxy, inclua a diretiva proxy_cache_path no contexto http{} de nível superior. Para especificar como as solicitações são armazenadas em cache, você também pode adicionar a diretiva proxy_cache_key da seguinte forma.

proxy_cache_path /var/cache/nginx app1 keys_zone=PROXYCACHE:100m inactive=60m max_size=500m;
proxy_cache_key  "$scheme$request_method$host$request_uri";
add_header X-Cache-Status $upstream_cache_status;
proxy_cache_min_uses 3;

Em seguida, ative o cache na diretiva de localização.

location / {
	proxy_pass http://127.0.0.1:3000;
	proxy_cache        PROXYCACHE;
	proxy_cache_valid 200 302 10m;
	proxy_cache_valid 404      1m;
}

Para definir condições sob as quais o NGINX não envia conteúdo em cache e não armazena uma resposta do servidor upstream, inclua as diretivas proxy_cache_bypass e proxy_no_cache.

 
proxy_cache_bypass  $cookie_nocache $arg_nocache$arg_comment;
proxy_no_cache        $http_pragma $http_authorization;

Ajustando o Desempenho do Cache do Proxy

As seguintes diretivas são úteis para ajustar o desempenho do cache do proxy. Elas também têm os mesmos significados que as diretivas FastCGI.

proxy_cache_min_uses 3;
proxy_cache_revalidate on;
proxy_cache_use_stale error timeout updating http_500;
proxy_cache_background_update on;
proxy_cache_lock on;

Para mais informações e diretivas de configuração de cache, consulte a documentação dos dois principais módulos ngx_http_fastcgi_module e ngx_http_proxy_module.

Recursos Adicionais: Armazenamento em Cache de Conteúdo NGINX e Dicas para Melhorar o Desempenho do WordPress.

Source:
https://www.tecmint.com/cache-content-with-nginx/