
Archivos Varnish: default.vcl y /etc/sysconfig/varnish en Centos 6.3
Actualmente en mi servidor dedicado están trabajando varios Sistemas de Gestión de Contenidos (CMS) en diferentes sitios web. Aunque el proxy-cache Varnish lo tenía instalado hace tiempo no trabajaba bien (pienso que no lo hacía en absoluto).
Ahora, y después de docenas de búsquedas en la red, he dado con una configuración que está funcionando bien y he ganado en velocidad de carga de las páginas al menos un 50%.
Como sobre Varnish cache hay muchísima información en Internet, os dejo directamente el código de los archivos fundamentales de Varnish 2.1.15 para Centos 6.3: /etc/varnish/default.vcl y /etc/sysconfig/varnish
NOTA. Se asume que en la configuración de Apache (/etc/httpd/conf/httpd.conf) tenemos el comando Listen apuntando al puerto 8080:
Listen 8080
Y de igual modo los servidores virtuales:
<VirtualHost *:8080>
De este modo Varnish escucha y cachea en el puerto 80 y pasa lo que no debe cachearse a Apache que escucha en el puerto 8080.
/etc/varnish/default.vcl
# This is a basic VCL configuration file for varnish. See the vcl(7)
# man page for details on VCL syntax and semantics.
#
# Default backend definition. Set this to point to your content
# server.
### modificar 111.222.333.444 por la IP de tu server ##
backend default {
.host = "127.0.0.1";
#.host = "111.222.333.444";
.port = "8080";
.connect_timeout = 600s;
.first_byte_timeout = 600s;
.between_bytes_timeout = 600s;
.max_connections = 250;
}
acl purge {
"localhost";
"127.0.0.1";
"111.222.333.444"/24;
}
acl CTRLF5 {
"111.222.333.444";
}
sub vcl_hit {
if (client.ip ~ CTRLF5) {
if (req.http.pragma ~ "no-cache" || req.http.Cache-Control ~ "no-cache")
{
set obj.ttl = 0s;
return(pass);
}
else { return(deliver); }
}
else { return(deliver); }
}
sub vcl_hit {
if (!obj.cacheable) {
return (pass);
}
if (req.request == "PURGE") {
set obj.ttl = 0s;
error 200 "Purged.";
}
return (deliver);
}
sub vcl_recv {
### Joomla, Pligg ###
if (req.url ~ "^/administrator" ||
req.url ~ "^/component/banners" ||
req.url ~ "^/contacto.html" ||
req.url ~ "^/hablame-del-mar/login.php" ||
req.url ~ "^/hablame-del-mar/login" ||
req.request == "POST") {
return (pass);
}
# remove ?ver=xxxxx strings from urls so css and js files are cached.
# Watch out when upgrading WordPress, need to restart Varnish or flush cache.
set req.url = regsub(req.url, "\?ver=.*$", "");
# Metemos el X-Forwarder-for
remove req.http.X-Forwarded-For;
set req.http.X-Forwarded-For = client.ip;
# Si el backend tarda mucho en generar la pagina sirve el objeto expirado.
set req.grace = 2m;
# Si el metodo no es el esperado no lo permitimos
if (req.request != "GET" &&
req.request != "HEAD" &&
req.request != "POST" &&
req.request != "PURGE") {
error 405 "Method Not Allowed";
}
# Dejamos pasar el POST sin cachear
if (req.request == "POST") {
return (pass);
}
if (req.url ~ "\.(png|gif|jpg|ico|jpeg|swf|css|js)$") {
unset req.http.cookie;
}
// Remove has_js and Google Analytics __* cookies.
set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(__[a-z]+|has_js)=[^;]*", "");
// Remove a ";" prefix, if present.
set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", "");
// Remove empty cookies.
if (req.http.Cookie ~ "^\s*$") {
unset req.http.Cookie;
}
# Filtro de purgado
if (req.request == "PURGE") {
if (!client.ip ~ purge) {
error 405 "Method Not Allowed";
}
### WordPress ###
# Pass anything other than GET and HEAD directly.
if (req.request != "GET" && req.request != "HEAD") {
return( pass );
} /* We only deal with GET and HEAD by default */
# remove cookies for comments cookie to make caching better.
set req.http.cookie = regsub(req.http.cookie, "1231111111111111122222222333333=[^;]+(; )?", "");
# never cache the admin pages, or the server-status page, or your feed? you may want to..i don't
if (req.request == "GET" && (req.url ~ "(wp-admin|bb-admin|server-status|feed)")) {
return(pipe);
}
# don't cache authenticated sessions
if (req.http.Cookie && req.http.Cookie ~ "(wordpress_|PHPSESSID)") {
return(lookup);
}
return( lookup );
}
# La autenticacion la dejamos pasar hasta el backend sin cachear
if (req.http.Authorization) {
/* Not cacheable by default */
return (pass);
}
# Si la peticion tiene cookie la cacheamos igualmente.
if (req.request == "GET" && req.http.cookie) {
return(lookup);
}
# Handle compression correctly. Different browsers send different
# "Accept-Encoding" headers, even though they mostly all support the same
# compression mechanisms. By consolidating these compression headers into
# a consistent format, we can reduce the size of the cache and get more hits.
# @see: http:// varnish.projects.linpro.no/wiki/FAQ/Compression
if (req.http.Accept-Encoding) {
if (req.http.Accept-Encoding ~ "gzip") {
# If the browser supports it, we'll use gzip.
set req.http.Accept-Encoding = "gzip";
}
else if (req.http.Accept-Encoding ~ "deflate") {
# Next, try deflate if it is supported.
set req.http.Accept-Encoding = "deflate";
}
else {
# Unknown algorithm. Remove it and send unencoded.
unset req.http.Accept-Encoding;
}
}
return (lookup);
}
sub vcl_hash {
if (req.http.Cookie) {
set req.hash += req.http.Cookie;
}
if (req.http.Accept-Encoding ~ "gzip") {
set req.hash += "gzip";
}
else if (req.http.Accept-Encoding ~ "deflate") {
set req.hash += "deflate";
}
}
sub vcl_miss {
if (req.request == "PURGE") {
error 404 "Not in cache.";
}
}
sub vcl_fetch {
set beresp.ttl = 2m;
set beresp.grace = 1h;
# Unset the "etag" header (suggested)
unset beresp.http.etag;
if( req.request != "POST" ) {
unset beresp.http.set-cookie;
}
if (beresp.http.set-cookie ~ "sessionid" || beresp.http.set-cookie ~ "csrftoken") {
return (pass);
} else {
return (deliver);
}
if (req.url ~ "\.(png|gif|jpg|ico|jpeg|swf|css|js)$") {
unset req.http.cookie;
}
// Varnish determined the object was not cacheable
if (!beresp.cacheable) {
set beresp.http.X-Cacheable = "NO:Not Cacheable";
} elsif(req.http.Cookie ~"(UserID|_session)") {
// You don't wish to cache content for logged in users
set beresp.http.X-Cacheable = "NO:Got Session";
return(pass);
} elsif ( beresp.http.Cache-Control ~ "private") {
// You are respecting the Cache-Control=private header from the backend
set beresp.http.X-Cacheable = "NO:Cache-Control=private";
return(pass);
} elsif ( beresp.ttl < 1s ) {
// You are extending the lifetime of the object artificially
set beresp.ttl = 300s;
set beresp.grace = 300s;
set beresp.http.X-Cacheable = "YES:Forced";
} else {
// Varnish determined the object was cacheable
set beresp.http.X-Cacheable = "YES";
}
# No cachear si lo dice cache-control
if( beresp.http.Pragma ~ "no-cache" ||
beresp.http.Cache-Control ~ "no-cache" ||
beresp.http.Cache-Control ~ "private" ||
beresp.http.Cache-Control ~ "max-age=0" ||
beresp.http.Cache-Control ~ "must-revalidate" ||
beresp.http.Cache-Control ~ "no-store" ||
beresp.http.Cache-Control ~ "private" ) {
return(pass);
}
return (deliver);
}
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
return (deliver);
}
sub vcl_error {
set obj.http.Content-Type = "text/html; charset=utf-8";
synthetic {"
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>"} obj.status " " obj.response {"</title>
</head>
<body>
<h1>Error "} obj.status " " obj.response {"</h1>
<p>"} obj.response {"</p>
<h3>Guru Meditation:</h3>
<p>XID: "} req.xid {"</p>
<hr>
<p>Varnish cache server</p>
</body>
</html>
"};
return (deliver);
}
/etc/sysconfig/varnish
VARNISH_MIN_THREADS=1
VARNISH_MAX_THREADS=1000
VARNISH_THREAD_TIMEOUT=120
VARNISH_TTL=120
NFILES=131072
MEMLOCK=82000
VARNISH_MEMORY_SIZE=10G
VARNISH_STORAGE_SIZE=20G
VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1
VARNISH_ADMIN_LISTEN_PORT=6082
VARNISH_LISTEN_PORT=80
DAEMON_OPTS="-a :80 \
-T localhost:6082 \
-f /etc/varnish/default.vcl \
-u varnish -g varnish \
-S /etc/varnish/secret \
-s malloc,2046m"
Con esta última configuración (-s malloc,2046m") Varnish guarda la cache en la memoria RAM del servidor. Para que lo haga en disco deberá cambiarse la última por: -s file,/var/lib/varnish/varnish_storage.bin,2G"
Hay que tener en cuenta que si se copia y se pega este código directamente puede dar lugar a errores por los espacios y saltos de línea ocultos. Mejor si se pega antes en un editor de texto simple como el bloc de notas de Windows.








