Clicky

Ejemplo de configuración de Varnish cache para Joomla!, Wordpress y Pligg

Varnish cache - logo

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.

Jesus_Caceres