Trucos de Varnish

Bueno ya hemos hablado mucho de Varnish, pero es que este acelerador HTTP da para mucho. Hoy vamos a contar unos cuantos consejos a la hora de trabajar con Varnish.

Como contamos al principio, una de las primeras tareas antes ni tan siquiera de instalar Varnish es distinguir a los usuarios de nuestra web para saber si la mayoría de las visitas son “stateless” (sin estado) o “stateful”. Solo sacaremos de verdad partido a Varnish si el grueso de las peticiones son “stateless”.

8140086323_ebbbff950e_z.jpg
304/366 Nail Varnish

Limpiar las request

Varnish para cachear las respuestas genera una clave utilizando entre otras cosas la url de la petición. Por ejemplo si queremos cachear https://jesuslc.com/ tendremos que:

generan claves distintas por lo que si las cacheamos estaremos llenando nuestra memoria con “basura”. Así que la mejor opción es limpiar todas estas urls junto para dejarlas lo más estándar posibles. Eso lo podemos conseguir con expresiones regulares dentro de la subrutina vcl_recv:

if (req.url ~ "(\?|&)(utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl)=") { set req.url = regsuball(req.url, "&(utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl)=([A-z0-9_\-\.%25]+)", ""); set req.url = regsuball(req.url, "\?(utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl)=([A-z0-9_\-\.%25]+)", "?"); set req.url = regsub(req.url, "\?&", "?"); set req.url = regsub(req.url, "\?$", ""); } Lo mismo pasará si utilizamos parámetros en nuestras URL’s, tendremos que escribir expresiones regulares para intentar minimizar el numero de objetos “inútiles” en caché.

De igual manera pasa con las cookies, no podemos cachearlas, o no debemos, porque las cookies personalizan/categorizan a nuestros usuarios por lo que también debemos limpiarlas, tanto las cookies de analytics como las propias:

  set req.http.Cookie = regsuball(req.http.Cookie, "__utm.=[^;]+(; )?", "");
  set req.http.Cookie = regsuball(req.http.Cookie, "_ga=[^;]+(; )?", "");
  set req.http.Cookie = regsuball(req.http.Cookie, "_gat=[^;]+(; )?", "");
  set req.http.Cookie = regsuball(req.http.Cookie, "utmctr=[^;]+(; )?", "");
  set req.http.Cookie = regsuball(req.http.Cookie, "utmcmd.=[^;]+(; )?", "");
  set req.http.Cookie = regsuball(req.http.Cookie, "utmccn.=[^;]+(; )?", "");

Se eliminan de una manera parecida a los parámetros de las url.

gzip deflate, compresión

Si esto nos suena a chino no tenemos que preocuparnos, a veces Varnish empieza a dar “Guru Meritation” y no sabemos muy bien por qué. Una razón puede ser la compresión que hace el servidor http (apache, nginx,…) de las respuestas. Si usamos compresión en las respuestas, puede que el servidor responda con un 200, pero la cabecera Content-Length  0, lo que hace que Varnish a veces “se lie”. No tengo claro por que a veces pasa, pero lo mejor es desactivar la compresión gzip y probar si todo vuelve a la normalidad.

No es una solución muy ortodoxa, pero a veces Varnish da demasiados dolores de cabeza y su configuración puede ser tediosa.

Comprobando la salud de los servidores

Si tenemos un pool de servidores para servir peticiones y es Varnish el “encargado” de balancear, deberemos darle los medios suficientes para saber que servidor esta disponible. Una manera sencilla es configurar la rutina probe para ir haciendo peticiones periódicas

  .probe = {
    #.url = "/"; # short easy way (GET /)
    # We prefer to only do a HEAD /
    .request =
      "HEAD / HTTP/1.1"
      "Host: localhost"
      "Connection: close"
      "User-Agent: Varnish Health Probe";

    .interval  = 5s; # check the health of each backend every 5 seconds
    .timeout   = 1s; # timing out after 1 second.
    .window    = 5;  # If 3 out of the last 5 polls succeeded the backend is considered healthy, otherwise it will be marked as sick
    .threshold = 3;
  }

Con esto estamos probando la URL / cada 5 segundos con una peticion HEAD.

Purge

Una de los problemas que nos encontramos con Varnish, es limpiar el contenido ya cacheado de manera selectiva. La opción más sencilla es enviar una petición PURGE con la URL que queremos eliminar de la caché, pero si esto lo usase un usuario “malintencionado” podría descachearnos siempre todo el sitio web. Para que esto no suceda, debemos configurar los ACL, es decir, indicarle a Varnish que IP’s son seguras para hacer PURGE, eso se hace en la rutina ACL:

acl purge {
  # ACL we'll use later to allow purges
  "localhost";
  "127.0.0.1";
  "::1";
}

ESI: Cachear “trozitos” de la página con diversos ttl

En un primer momento, cuando empezamos con Varnish, las páginas o se cachean o no se cachean. Más adelante, cuando cogemos un poco de soltura con el VCL podemos elegir solo cachear ciertas páginas o si encontramos un parámetro en la url no cachearla, pero en cambio si no está ese parámetro entonces sí. La verdad es que hay infinidad de variaciones.

Entonces es cuando decidimos dar un paso más y utiliza Edge Side Include (ESI). ESI con una serie de tags que Varnish entiende y con los que podemos dividir cada página en “trozitos” con cabecera, el pie, el menú lateral, la barra de navegación,… y asignar a cada elemento/”trozito” un tiempo de vida, e incluso elegir si cachearlo o no. La parte más difícil sin duda está en dividir la página en trozos y establecer reglas para TTL, cacheo y descacheo.

error 503 guru meditation varnish

Es el error más típico de Varnish, incluso cuando buscamos “Guru Meditation” en la Wikipedia aparecen referencias a Varnish. Si queremos saber por qué esta fallando Varnish con un 503 Guru Meditation debemos ver el log de Varnish y filtrarlo así:

$ varnishlog -b -q 'FetchError'

Normalmente estos errores se dan porque: – no hay conexión con el backend: El backend no responde y no puede proporcionarnos respuesta. – Cierre de la conexión por alguno de los extremos: Puede ser que Varnish se “canse” de esperar porque el backend sea lento o porque el backend cierre la conexión por algo extraño.

Recargar una nueva configuración de Varnish sin reiniciar Lo mejor para hacer esto es utilizar varnishadm, esto nos abrirá la consola REPL de Varnish donde podremos ejecutar los siguientes comandos:

/opt # varnishadm
200
-----------------------------
Varnish Cache CLI 1.0
-----------------------------
Linux,4.4.16-boot2docker,x86_64,-junix,-smalloc,-smalloc,-hcritbit
varnish-4.1.2 revision 0d7404e

Type 'help' for command list.
Type 'quit' to close CLI session.

varnish> vcl.load newconfig01 /opt/varnish.vcl
200
VCL compiled.

varnish> vcl.use newconfig01
200
VCL 'newconfig01' now active
varnish> quit
500
Closing CLI connection

La primera linea el vcl.load lo que hace es compilar Varnish, si hubiese algún error nos lo indicaría en este paso. con la segunda linea vcl.use indicamos a Varnish que configuración usar.

Disclaimer

Si estamos hartos de Varnish o si lo amamos porque el performance de nuestro sitio es asombroso siempre podemos “inscribirnos” en la Religión de Varnish. Esta religión/secta es una invención de los chicos de EReplublik, que se nota que han luchado bastante con Varnish 😉 Si te interesa aquí te dejo los libros 😉

Anuncios

5 comentarios en “Trucos de Varnish

  1. Que bueno consejos, me serán muy útiles, gracias, No tienes algún tuto para instalar el Varnish-Agent, para poder monitorizar en tiempo real, Gracias y Saludos

    Me gusta

Comenta la entrada

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s