Voy a explicar de forma sencilla como he implementado Varnish en este servidor, para acelerar algunas páginas que son casi estáticas, pero que se generan dinámicamente.
Ya hablamos sobre cómo acelerar la web con la caché, y aunque como servidor web trabajo con Cherokee, que es bastante eficiente gestionando su propia caché, poner a Varnish delante tiene cieras ventajas.
La primera de ellas es que este blog se sirve mediante un proxy HTTP (el servidor original es el de Tornado), y en ese caso concreto Cherokee por ahora no implementa caché :(.
Así que, por una parte me beneficio de las virtudes de Varnish para todo el servidor, y además consigo caché donde no tenía, a cambio de dedicar un poco de memoria al invento.
Mi servidor ahora funciona tal que así:
Estoy trabajando con la versión 2.1.2 instalada desde fuentes, porque en la distro de mi servidor está la 2.1.0, y parece que merece la pena actualizar.
Hay que llevar cuidado con los requisitos, e instalar los paquetes de desarrollo de ncurses, porque el configure no se quejará, pero luego nos daremos cuenta de que no tenemos herramientas bastante útiles (como varnishstat o varnishtop).
Hay distintas formas de desplegar el caché, y a mi lo que me ha dado mejor resultado es:
- Poner a
Cherokee escuchando en el puerto 80, pero solo en 127.0.0.1. Esto es porque si usamos otro puerto, podemos tener problemas en algunas redirecciones (tengo pendiente ver si es un bug).
- Poner a
Varnish en el puerto 80, pero en la interfaz pública del servidor.
De esta forma, nuestro default.vcl empezará con:
backend default {
.host = "127.0.0.1";
.port = "80";
}
Así indicamos donde estará nuestro backend (Cherokee en este caso).
Lo siguiente que he hecho ha sido ignorar las cookies en todos los contenidos que sé que no las utilizan, y por lo tanto los queremos cacheados:
sub vcl_recv {
# cache static content, even when there are cookies
if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|pdf)$") {
unset req.http.Cookie;
if (req.http.Accept-Encoding) {
remove req.http.Accept-Encoding;
}
}
}
Todas esas extensiones sabemos que:
- No cambian dinámicamente, y sobretodo no cambian por el hecho de haber una cookie. Por ejemplo, cuando trabajamos con usuarios autenticados.
- Ya están comprimidos, así que podemos descartar el
Accept-Encoding porque nunca los volveremos a comprimir, de forma que simplificamos qué se almacena en la caché.
Con esto ya es suficiente para arrancar Varnish.
Solo falta poner el servicio en el sistema de arranque (con init.d), porque instamamos desde fuentes. Por ejemplo, podemos usar:
#!/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DESC="Varnish"
NAME=varnish
DAEMON=/usr/local/sbin/varnishd
SCRIPTNAME=/etc/init.d/$NAME
test -f /etc/default/varnish && source /etc/default/varnish
# Gracefully exit if the package has been removed.
test -x $DAEMON || exit 0
case "$1" in
start)
cd /
echo -n "Starting $DESC: $NAME"
$DAEMON $OPTIONS 2>&1 >/dev/null < /dev/null
echo "."
;;
stop)
echo -n "Stopping $DESC: $NAME"
pkill varnishd
echo "."
;;
*)
echo "Usage: $SCRIPTNAME {start|stop}" >&2
exit 3
;;
esac
exit 0
Y en /etc/default/varnish ponemos los parámetros para el servicio:
OPTIONS="-f /usr/local/etc/varnish/default.vcl -s malloc,64M -a IP_PUBLICA:80"
He puesto IP_PUBLICA en lugar de mi IP, y he dedicado 64MB de memoria a la caché, que no será persistente en disco (ahora mismo no le veo mucho sentido a la persistencia de la caché, aunque si reinicio Varnish, no habrá nada cacheado).
En mi caso (Ubuntu Server), ejecuto update-rc.d como corresponde para que el servicio arranque con el sistema, y ya estamos listos para trabajar.
Ya anticipé hace unos días los buenos resultados que estaba obteniendo con Varnish, y a nivel de efectividad de la caché ya tengo algunos datos recogidos con varnishstat (herramienta incluída en el paquete de Varnish):
34863 Client requests received
11051 Cache hits
22190 Cache misses
Hay más datos, pero estos son los más relevantes para los últimos 5 días. Eso es un 31,69% de las peticiones servidas desde la caché, contra un 63.64% de peticiones que acabaron en Cherokee.
Estos valores no están mal, porque a fin de cuentas la mayoría de mis visitas van a las páginas nuevas en esta bitácora, que no son cacheables. Aún así, tengo pendiente prestarle más atención, a ver si puedo mejorar el resultado :P.
Finalmente comentar que he detectado un problema entre Varnish y Cherokee con el Keep-Live, y por ahora tendremos que usar Cherokee sin Keep-Alive para evitar posibles errores 503 en Varnish si se da el timeout. Curiosamente me he dado cuenta porque aguanto poco tráfico, y no es un problema si tenemos un servidor muy ocupado, donde sí sería realmente útil una caché como la que nos propociona Varnish :P.