Acelera tu web con Nginx como caché de proxy inverso

Optimizar el Web Performance es una asignatura pendiente que continuamente debemos de trabajar. Existen múltiples soluciones para mejorar nuestros tiempos de respuesta. Ya hablamos de algunas recomendaciones y analizadores para mejorar el rendimiento en artículos anteriores, pero hoy vamos a ver como acelerar una web utilizando Nginx como Caché de Proxy Inverso.

¿Que es una caché de Proxy Inverso?

En informática, un proxy inverso es un tipo de servidor situado entre el cliente y el servidor o servidores web que recupera los recursos de estos. Estos recursos se devuelven al cliente como si los hubiera devuelto el propio servidor web. Básicamente es un intermediario que puede actuar de distintos roles.

Las posibles aplicaciones que le podemos dar a este proxy es emplearlo como un firewall a una red interna, como balanceador de carga, como herramienta para aplicar un AB Testing o el motivo de este artículo, como servidor de caché de estáticos.

Básicamente este servidor utilizado como caché, consulta al servidor web si no tuviera el recurso solicitado, ocurriendo un MISS y guardando este recurso en memoria. La próxima petición al mismo recurso la sirve el propio proxy de una manera muy eficiente produciéndose un HIT y evitando la llamada al servidor web durante un TTL determinado. De esta manera podemos montar un servidor de estáticos centralizado y desde el que sirvamos todo nuestro contenido estático.

Existen distintas tecnologías que nos permiten cumplir este escenario. Uno de las herramientas más conocidas es Varnish, pero Nginx a parte de servidor web también se puede configurar para que actúe como caché de proxy inverso. Leyendo varios artículos de comparativas y benchmarks la diferencia es mínima, por lo que hoy nos vamos a centrar en el escenario Nginx-Nginx.

Sin embargo podríamos representar el mismo escenario con distintas combinaciones: Varnish-Apache, Varnish-Nginx o Nginx-Apache, siendo el primero de la pareja el servidor de caché y el segundo el servidor web.

¿Por que Nginx?

Igual que Varnish, Nginx es capaz de actuar de caché web pero no todos los administradores de sistemas conocen esta faceta. Nginx puede servir contenido estático directamente de una forma muy eficiente y puede actuar como cache colocado como frontal, al igual que lo haría Varnish. Mientras Varnish su único cometido es el de actuar como cache con avanzadas opciones, Nginx es polivalente y nos ofrece varias alternativas.

La verdad es que yo no sabría por cual de las dos opciones declinarme, pero la decisión de usar únicamente nginx, es para no introducir nuevas tecnologías que aprender y mantener en nuestra infraestructura, y parece que la configuración de nginx es mucho mas sencilla que la de Varnish.

Montando la infraestructura

Instalar Nginx

Para instalar nginx en nuestro servidor simplemente ejecutamos el siguiente comando:

sudo apt-get install nginx

Por defecto nginx se instalará en tu sistema escuchando en el puerto 80, sirviendo un html estático de bienvenida. Vamos a ver como configurar nginx.

Configurar el servidor web

Lo primero de todo debemos de tener en cuenta que el servidor web que leerá los recursos de nuestro sistema de ficheros ya no debe de escuchar en el puerto 80, pues en su lugar se pondrá el proxy.

Vamos a crear una carpeta donde estarán alojados nuestros recursos:

mkdir /var/www/assets

Tras esto vamos a configurar nuestro nginx para que escuche en el puerto 81, que defina como raiz nuestro directorio de recursos y que incluya un tiempo de expiración del recurso de 12 horas. Esto se puede configurar a través de expresiones regulares que permite la configuración. Para ello generamos el siguiente fichero /etc/nginx/sites-available/static-server

server {
listen 81;
server_name {{tu ip o subdominio}};
access_log /var/log/nginx/static-server.log;

location ~* \. (?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
expires 12h;
root /var/www/assets;
add_header Cache-Control "public";
}
}

Y finalmente lo moveremos a /etc/nginx/sites-enabled/static-server. Si ahora hacemos una petición a un recurso a través del puerto 81 deberíamos poder recibirlo.

Configurar el proxy caché

Para configurar nginx para que actúe de cache vamos a usar la directiva proxy_cache_path. Esta directiva indica un directorio de tu máquina donde se almacenará todos los recursos que se vayan cacheando .

Este directorio debería de contener el grupo www-data y permisos 700 para que el prox pueda escribir correctamente. Además en esta directiva se le indica un identificador keys_zone que define el nombre, el tamaño máximo de esta caché con max_size y los niveles de indirección de la jerarquía de las carpetas en la caché.

Además nos apoyaremos en otra directiva proxy_cache_key, que es la clave para almacenar los recursos cacheados. Básicamente nginx hace un hash de esta estructura, de esta manera poder elegir el nivel de caché, por ejemplo si utiliza el mismo parámetro o no en la url.

Una vez teniendo estas dos directivas claras, vamos a indicar que el proxy escuche en el puerto 80, y que toda petición que venga inspeccione la zona de caché que hemos definido y en caso contrario consulte contra nuestro servidor web escuchando en el puerto 81 con la directiva proxy_pass.

Además Nginx incluye una cabecera llamada X-Proxy-Cache que indica al cliente si el recurso lo devolvió la caché (HIT) o tuvo que consultar al servidor web (MISS). Esta información es especialmente interesante para depurar que todo está funcionando correctamente.

A continuación dejo la configuración completa del caching server:

#/etc/nginx/sites-enabled/caching-server
proxy_cache_path /tmp/nginx levels=1:2 keys_zone=assets_zone:10m inactive=60m;
proxy_cache_key "$scheme$request_method$host$request_uri";
server {
listen 80;
server_name {{tu ip o subdominio}};
access_log /var/log/nginx/caching-server.log;
location /static/ {
proxy_cache assets_zone;
add_header X-Proxy-Cache $upstream_cache_status;
include proxy_params;
proxy_pass http://localhost:81/;
}
}

Espero que este artículo te haya resultado interesante y útil y espero que nos cuentes tus experiencias sobre como has optimizado tu web y los problemas a los que te has enfrentado y soluciones que implantaste.

Enlaces relacionados

https://serversforhackers.com/nginx-caching

https://www.digitalocean.com/community/tutorials/understanding-nginx-http-proxying-load-balancing-buffering-and-caching

Artículo publicado en https://adrianalonso.es/devops/acelera-tu-web-con-nginx-como-cache-de-proxy-inverso/

Full Stack Web Developer — adrianalonso.es

Full Stack Web Developer — adrianalonso.es