Cómo cachear contenido en NGINX

NGINX es un servidor web de alto rendimiento consolidado de código abierto que acelera la entrega de contenido y aplicaciones, mejora la seguridad y aumenta la escalabilidad. Uno de los casos de uso más comunes de Nginx es el almacenamiento en caché de contenido, que es la forma más efectiva de mejorar el rendimiento de un sitio web.

Leer también: 10 principales herramientas de almacenamiento en caché de código abierto para Linux

Puede utilizar NGINX para acelerar servidores de origen locales configurándolo para almacenar en caché las respuestas de servidores ascendentes y también para crear servidores de borde para redes de entrega de contenido (CDNs). NGINX alimenta algunas de las CDNs más grandes.

Cuando se configura como caché, NGINX:

  • almacena en caché contenido estático y dinámico.
  • mejora el rendimiento del contenido dinámico con microcaché.
  • sirve contenido obsoleto mientras se revalida en segundo plano para obtener un mejor rendimiento.
  • anula o establece encabezados de control de caché, y más.

En este artículo, aprenderá cómo configurar NGINX como almacenamiento en caché de contenido en Linux para que sus servidores web funcionen de la manera más eficiente posible.

Requisitos previos:

Debe tener NGINX instalado en su servidor Linux, si no, siga estas guías para instalar Nginx:

Almacenar en caché contenido estático en Nginx

El contenido estático es el contenido de un sitio web que permanece igual (no cambia) en todas las páginas. Ejemplos de contenido estático incluyen archivos como imágenes, videos, documentos; archivos CSS y archivos JavaScript.

Si tu sitio web hace uso de mucho contenido estático, entonces puedes optimizar su rendimiento habilitando la caché del lado del cliente donde el navegador almacena copias del contenido estático para un acceso más rápido.

La siguiente configuración de ejemplo es buena, simplemente reemplaza www.example.com con la URL de tu nombre de sitio web y realiza modificaciones en otros nombres de ruta según corresponda.

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

Almacenar en caché contenido dinámico en Nginx

NGINX utiliza una caché persistente basada en disco ubicada en algún lugar del sistema de archivos local. Así que comienza creando el directorio de disco local para almacenar el contenido en caché.
# mkdir -p /var/cache/nginx

A continuación, establece la propiedad adecuada en el directorio de caché. Debería ser propiedad del usuario NGINX (nginx) y del grupo (nginx) de la siguiente manera.

# chown nginx:nginx /var/cache/nginx

Ahora continúa para ver cómo habilitar el contenido dinámico en Nginx en la siguiente sección.

Habilitar la caché FastCGI en NGINX

FastCGI (o FCGI) es un protocolo ampliamente utilizado para la interfaz de aplicaciones interactivas como PHP con servidores web como NGINX. Es una extensión del CGI (Common Gateway Interface).

La principal ventaja de FCGI es que gestiona múltiples solicitudes de CGI en un solo proceso. Sin él, el servidor web tendría que abrir un nuevo proceso (que debe ser controlado, procesar una solicitud y cerrarse) para cada solicitud de cliente para un servicio.

Para procesar scripts de PHP en una implementación de pila LEMP, NGINX utiliza FPM (FastCGI Process Manager) o PHP-FPM, una implementación de PHP FastCGI alternativa popular. Una vez que el proceso PHP-FPM está en ejecución, NGINX está configurado para enviar solicitudes a él para su procesamiento. Por lo tanto, NGINX también se puede configurar para almacenar en caché las respuestas del servidor de aplicaciones de fondo PHP-FPM.

Bajo NGINX, la caché de contenido FastCGI se declara utilizando una directiva llamada fastcgi_cache_path en el contexto http{} de nivel superior, dentro de la estructura de configuración de NGINX. También se puede agregar el fastcgi_cache_key que define una clave (identificador de solicitud) para la caché.

Además, para leer el estado de la caché ascendente, añade la directiva add_header X-Cache-Status dentro del contexto http{} – esto es útil para propósitos de depuración.

Suponiendo que el archivo de configuración del bloque del servidor de su sitio se encuentra en /etc/nginx/conf.d/testapp.conf o /etc/nginx/sites-available/testapp.conf (bajo Ubuntu y sus derivados), abre el archivo para editarlo y añade las siguientes líneas en la parte superior del archivo.

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

La directiva fastcgi_cache_path especifica el número de parámetros que son:

  • /var/cache/nginx – la ruta al directorio de disco local para la caché.
  • levels – define los niveles de jerarquía de una caché, establece una jerarquía de directorios de dos niveles bajo /var/cache/nginx.
  • keys_zone (nombre:tamaño) – permite la creación de una zona de memoria compartida donde se almacenan todas las claves activas y la información sobre los datos (meta). Tenga en cuenta que almacenar las claves en memoria acelera el proceso de verificación, haciendo que sea más fácil para NGINX determinar si es un MISS o un HIT, sin necesidad de verificar el estado en disco.
  • inactive – especifica la cantidad de tiempo después del cual los datos en caché que no han sido accedidos durante el tiempo especificado se eliminan de la caché independientemente de su frescura. Un valor de 60m en nuestra configuración de ejemplo significa que los archivos no accedidos después de 60 se eliminarán de la caché.
  • max_size – especifica el tamaño máximo de la caché. Hay más parámetros que puedes usar aquí (lee la documentación de NGINX para obtener más información).

Las variables en la directiva fastcgi_cache_key se describen a continuación.

NGINX las utiliza para calcular la clave (identificador) de una solicitud. Es importante que, para enviar una respuesta en caché al cliente, la solicitud tenga la misma clave que una respuesta en caché.

  • $scheme – esquema de solicitud, HTTP o HTTPS.
  • $request_method – método de solicitud, generalmente “GET” o “POST”.
  • $host – puede ser el nombre de host de la línea de solicitud, o el nombre de host del campo de encabezado de solicitud “Host”, o el nombre del servidor que coincide con una solicitud, en orden de precedencia.
  • $request_uri – significa el URI de solicitud original completo (con argumentos).

También, la variable $upstream_cache_status en la directiva add_header X-Cache-Status se calcula para cada solicitud a la que NGINX responde, ya sea un MISS (respuesta no encontrada en la caché, obtenida del servidor de aplicaciones) o un HIT (respuesta servida desde la caché) u otro de los valores admitidos.

A continuación, dentro de la directiva location que pasa las solicitudes de PHP a PHP-FPM, utiliza las directivas fastcgi_cache para activar la caché que acabas de definir arriba.

También establece el tiempo de almacenamiento en caché para diferentes respuestas usando la directiva fastcgi_cache_valid como se muestra.

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

Si solo se especifica el tiempo de almacenamiento en caché, como en nuestro caso, solo se almacenan en caché las respuestas 200, 301 y 302. Pero también puedes especificar las respuestas explícitamente o utilizar cualquier (para cualquier código de respuesta):

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

Ajuste fino del rendimiento de almacenamiento en caché FastCGI en Nginx

Para establecer el número mínimo de veces que se debe realizar una solicitud con la misma clave antes de que se almacene en caché la respuesta, incluya la directiva fastcgi_cache_min_uses, ya sea en el contexto http{}, server{} o location{}.

fastcgi_cache_min_uses  3
Set Minimum Cache Usage

Para habilitar la revalidación de elementos de caché caducados mediante solicitudes condicionales con los campos de encabezado “If-Modified-Since” y “If-None-Match“, agregue la directiva fastcgi_cache_revalidate, dentro del contexto http{}, server{} o location{}.

fastcgi_cache_revalidate on;
Set Cache Re-validation

También puede indicarle a NGINX que entregue contenido en caché cuando el servidor de origen o el servidor FCGI estén inactivos, utilizando la directiva proxy_cache_use_stale, dentro de la directiva de ubicación.

Esta configuración de ejemplo significa que cuando NGINX recibe un error, un tiempo de espera y cualquiera de los errores especificados del servidor ascendente y tiene una versión caducada del archivo solicitado en el contenido en caché, entrega el archivo caducado.

proxy_cache_use_stale error timeout http_500;
Enable Serving of Stale Data

Otra directiva útil para ajustar el rendimiento de la caché FCGI es fastcgi_cache_background_update, que funciona en conjunto con la directiva proxy_cache_use_stale. Cuando se establece en on, instruye a NGINX para que sirva contenido obsoleto cuando los clientes soliciten un archivo que ha caducado o está en proceso de actualización desde el servidor upstream.

fastcgi_cache_background_update on;
Enable Cache Background Update

El fastcgi_cache_lock también es útil para ajustar el rendimiento de la caché en el sentido de que si varios clientes solicitan el mismo contenido que no está en la caché, NGINX solo enviará la primera solicitud al servidor upstream, almacenará en caché la respuesta y luego servirá las solicitudes de los otros clientes desde la caché.

fastcgi_cache_lock on;
Enable Cache Lock

Después de realizar todos los cambios anteriores en el archivo de configuración de NGINX, guárdelo y ciérrelo. Luego, compruebe la estructura de la configuración en busca de errores de sintaxis antes de reiniciar el servicio de NGINX.

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

A continuación, pruebe si la caché funciona correctamente, intente acceder a su aplicación web o sitio utilizando el siguiente comando curl (la primera vez debería indicar un MISS, pero las solicitudes posteriores deberían indicar un HIT como se muestra en la captura de pantalla).

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

Aquí hay otra captura de pantalla que muestra a NGINX sirviendo datos obsoletos.

Test Nginx Serving Stale Data

Añadiendo Excepciones para Evitar la Caché

Puede establecer condiciones bajo las cuales NGINX no debe enviar respuestas almacenadas en caché a los clientes, utilizando la directiva fastcgi_cache_bypass. Y para instruir a NGINX que no almacene en caché las respuestas del servidor remoto en absoluto, use la fastcgi_no_cache.

Por ejemplo, si desea que las solicitudes POST y las URLs con una cadena de consulta siempre se dirijan a PHP. Primero, declare un if para establecer la condición como sigue.

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

Luego active la excepción anterior en la directiva location que pasa las solicitudes PHP a PHP-FPM, utilizando las directivas fastcgi_cache_bypass y fastcgi_no_cache.

 
fastcgi_cache_bypass $skip_cache; 
fastcgi_no_cache $skip_cache;

Hay muchas otras partes de su sitio web para las cuales puede que no desee habilitar la caché de contenido. A continuación, se proporciona un ejemplo de configuración de NGINX para mejorar el rendimiento de un sitio web de WordPress, publicado en el blog de nginx.com.

Para utilizarlo, realice cambios (como el dominio, las rutas, los nombres de archivo, etc.) para reflejar lo que existe en su entorno.

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 la Caché Proxy en NGINX

NGINX también soporta el almacenamiento en caché de respuestas de otros servidores proxy (definidos por la directiva proxy_pass). Para este caso de prueba, estamos utilizando NGINX como un proxy inverso para una aplicación web de Node.js, de modo que habilitaremos NGINX como caché para la aplicación de Node.js. Todas las directivas de configuración utilizadas aquí tienen significados similares a las directivas FastCGI del apartado anterior, así que no las explicaremos de nuevo.

Para habilitar el almacenamiento en caché de respuestas desde un servidor proxy, incluya la directiva proxy_cache_path en el contexto http{} de nivel superior. Para especificar cómo se almacenan en caché las solicitudes, también puede agregar la directiva proxy_cache_key de la siguiente manera.

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;

A continuación, active la caché en la directiva de ubicación.

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 las condiciones bajo las cuales NGINX no envía contenido en caché y no almacena en caché una respuesta en absoluto desde el servidor ascendente, incluya las directivas proxy_cache_bypass y proxy_no_cache.

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

Ajuste fino del rendimiento de la caché de proxy

Las siguientes directivas son útiles para ajustar el rendimiento de la caché de proxy. También tienen los mismos significados que las directivas 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 obtener más información y directivas de configuración de caché, consulte la documentación de los dos módulos principales ngx_http_fastcgi_module y ngx_http_proxy_module.

Recursos adicionales: Almacenamiento en caché de contenido NGINX y Consejos para mejorar el rendimiento de WordPress.

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