La finalidad de este howto es la dotar a nuestros sites de un sistema
de caches para ahorrar ancho de banda en origen, aumentar el rendimiento
de los sites y protegernos de posibles fallas en los servidores origen,
para ello vamos a utilizar varnish para todo el tema de cacheo de
estaticos y nginx para gestionar el tema de multisite de una manera más
sencilla y eficiente de la que podriamos hacerlo con varnish.
El punto de entrada de la solución es varnish quien atiende al puerto 80 como si del servidor principal se tratara. En el puerto 81 estará corriendo nginx quien redireccionará todas las request que varnish no tenga en cache al servidor origen correcto, mediante proxy_pass.
Primero el fichero de configuración de varnish.
Como se ve en las primeras lineas del fichero de configuración defaul.vcl estamos poniendo como backend el nginx que corre en el puerto 81.
Ahora el fichero de configuración del nginx:
Por último solo nos queda probar que todo funciona como debe.
El punto de entrada de la solución es varnish quien atiende al puerto 80 como si del servidor principal se tratara. En el puerto 81 estará corriendo nginx quien redireccionará todas las request que varnish no tenga en cache al servidor origen correcto, mediante proxy_pass.
Primero el fichero de configuración de varnish.
# Backends backend default { .host = "127.0.0.1"; .port = "81"; } # ACL Purge acl limpia { "localhost"; "10.90.90.0"/24; "10.90.40.0"/24; "10.90.55.0"/24; } sub vcl_recv { # Metemos el X-Forwarder-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); } # Filtro de purgado if (req.request == "PURGE") { if (!client.ip ~ limpia) { error 405 "Method Not Allowed"; } 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); } return (lookup); } sub vcl_hit { if (!obj.cacheable) { return (pass); } if (req.request == "PURGE") { set obj.ttl = 0s; error 200 "Purged."; } return (deliver); } sub vcl_hash { 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 { # Si el backend tarda mucho en generar la pagina sirve el objeto expirado. set beresp.grace = 2m; if (beresp.http.Set-Cookie) { return (deliver); } # No cachear si tenemos autorizacion if (req.http.Authorization) { return(pass); } # 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);}
Como se ve en las primeras lineas del fichero de configuración defaul.vcl estamos poniendo como backend el nginx que corre en el puerto 81.
Ahora el fichero de configuración del nginx:
user nobody nogroup; worker_processes 1; error_log logs/error.log; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; upstream origen1 { server origen.prueba.com:80; } upstream origen2 { server origen2.example.com:80; } server { listen 81; server_name www.prueba.com; location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $http_host; proxy_pass http://origen1; } } server { listen 81; server_name www.example.com; location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $http_host; proxy_pass http://origen2; } } }En la configuración del nginx estamos definiendo varios servidores origen en funcion de la request que le esté pasando el varnish.
Por último solo nos queda probar que todo funciona como debe.