Varnish: il web accelerator per il tuo server.

Varnish e un web accelerator utilizzato per siti web dinamici con funzionalita di caching. Sono stati proprio I suoi creatori a definirlo in questo modo, in quanto il suo scopo principale e quello di velocizzare il front end di un sito web, ottimizzando l'accesso ad esso senza andare a mettere mano sul codice : semplicemente l'utilizzatore di questo prodotto open source non e costretto a modifcare il codice dellla sua applicazione.

Varnish è un web accelerator utilizzato per siti web dinamici con funzionalità di caching. Sono stati proprio I suoi creatori a definirlo in questo modo, in quanto il suo scopo principale è quello di velocizzare il front end di un sito web, ottimizzando l’accesso ad esso senza andare a mettere mano sul codice : semplicemente l’utilizzatore di questo prodotto open source non è costretto a modifcare il codice dellla sua applicazione. Rispetto ad altri prodotti, come ad esempio Squid, è stato pensato esclusivamente per il protocollo HTTP.

Lo si può utilizzare se si ha a disposizione una soluzione hosting dedicata o un VPS (Virtual Private Server), avendo l’utente la necessità di accedere con I privilegi di amministratore (root) per poter installare il software.

Flessibilità, la chiave del successo

Una caratteristica importante di Varnish è la flessibilità: infatti utilizza un suo linguaggio di configurazione, il VCL (Varnish Configuration Language), il quale viene poi tradotto in codice binario che viene eseguito all’arrivo di una richiesta da parte di un client. I vari file VCL sono divisi in subroutines. Quelle che un utente sicuramente utilizzerà saranno due:

  1. vcl_recv: è invocata all’arrivo di ogni richiesta. Il suo scopo è quello di decidere se servire la richiesta o meno, come farlo e quale backend utilizzare.
  2. vcl_fetch: è invocata ogni volta che viene restituito un documento dal backend. In questa subroutine si possono modificare gli header, e gestire I failure sui server di backend.
  3. vcl_hit: chiamata dopo che un lookup (vedi dopo) sulla cache viene eseguito e il documento viene trovato
  4. vcl_miss: chiamata dopo che un lookup (vedi dopo) sulla cache viene eseguito e il documento non viene trovato

In ogni subroutine possono essere intraprese delle azioni, tra le quali:

  • pass: richiesta e risposta passeranno da varnish senza essere salvate in cache
  • lookup: è chiamata solo in vcl_recv e indica che Varnish consegnerà il contenuto della cache, anche se esiste un’azione di pass sulla richiesta
  • pipe: in questo caso Varnish esegue una semplice operazionedi pass-through, senza andare a effettuare il parsing del contenuto
  • deliver: consegna l’oggetto in cache. Di solito viene invocata in vcl_fetch.

Esitono inoltre 3 importanti strutture dati: 

  • req: la richiesta dal client
  • beresp: la risposta dal backend, compresi gli header. In vcl_fetch la maggior parte del lavoro viene dedicao a questa struttura dati.
  • obj: l’oggetto in cache. 

Un’altra importante caratteristica di Varnish è il load balancing: esso può essere realizzato o utilizzando una policy round-robin, oppure in base ai contenuti della richiesta del client ( IP, header HTTP, URL della richiesta…).

Varnish, l’installazione e la configurazione

Una volta introdotto l’argomento possiamo a vedere più nel dettaglio il software. Innanzitutto dobbiamo installare il software. Utilizzando l’ultima versione di Ubuntu (la 12.04) è possibile effettuare l’operazione con un semplice comando:

            sudo apt-get install varnish

In alternativa è possibile compilare il codice sorgente reperibile alla pagina

            https://www.varnish-cache.org/releases/varnish-cache-3.0.1

Una volta installato, andiamo a vedere 2 file di configurazione che ci interessano: il primo ha full path name /etc/default/varnish e contiene, tra le altre, le opzioni con cui viene lanciato varnish. Questo è specificato nell’attributo DAEMON_OPTS, ad esempio

DAEMON_OPTS=      “-a :6081

                        -T localhost:6082

                        -u varnish -g varnish

                        -S /etc/varnish/secret

                        -s malloc,1G”

indica che Varnish sarà in ascolto sulla porta 6081, il management è sulla 6082, e utiliza una cache di 1GB.

Il secondo file di configurazione è /etc/varnish/default.vcl: esso contiene la definizione dei server di backend e le varie subroutines. Di default è definito un unico server di backend:

backend default {

   .host = “localhost”;

   .port = “8080”;

}

che rappresenta un server locale in ascolto sulla porta 8080. Nel caso volessimo definirne più di uno potremmo tranquillamente farlo, ad esempio:

backend web1 { .host = “192.168.0.234”;  .port = 8080; .probe = { .url = “/status.htm”; .interval = 5s; .timeout = 1s; .window = 5;.threshold = 3; }}

backend web2 { .host = “192.168.0.235”; .port = 8080; .probe = { .url = “/status.htm”; .interval = 5s; .timeout = 1s; .window = 5;.threshold = 3; }}

In questo caso abbiamo anche aggiunto l’opzione di probing dell’applicazione.In particolare varnish invierà una richiesta all’URL status.php dei server ogni 5 secondi(interval). Il timeout associato alla pagina è di 1 secondo e per considerare il server di backend attivo almeno almeno 2 (window-threshold) delle ultime 5 richieste(window) devono essere andate a buon fine.

La configurazione, seconda parte

Una volta creati, è possibile definire una policy di load balancing, ad esempio round robin, aggiungendo le seguenti righe al file di configurazione:

director default_director round-robin {
  { .backend = web1; }
  { .backend = web2; }
}

Per fare questo utilizziamo l’opzione director con cui possiamo raggruppare logicamente I server che creiamo. In questo caso abbiamo creato un gruppo logico con policy round robin, ma ne esistono molti altri:

                     random

                     client

                     dns

                     hash

che non spiegheremo nel dettaglio.

Per fare In modo che i documenti non vengano salvati in cache si può utilizzare l’opzione “pass”:

if (req.url ~ “^/status.php$” ||
 req.url ~ “^/update.php$” ||

req.url ~ “^/admin/build/features” ||
req.url ~ “^/info/.*$”) {
            return (pass);
}

Tutte le richieste verso i path indicati non verranno salvate in cache.

Un’altra feature che è possibile utilizzare sono le ACL (Access Control List). Nel caso in cui non volessimo che il contenuto di alcune pagine sia accessibile potremmo fare in questo modo:

1.  Definiamo un ACL contenente gli indirizzi fidati

            acl internal {

            “192.168.0.0”/24;
            }

2.  Nella subroutine vcl_recv andiamo a negare l’accesso ad una data risorsa (private.php)se la richiesta non arriva dagli indirizzi definiti al punto 1, mostrando un errore al client.

            sub vcl_recv {
             …
                        if (req.url ~ “^/private.php$” && !client.ip ~ internal) {
                        error 404 “Page not found
                        }
            }

Infine un’altra importante opportunità che dà Varnish è quella di continuare a servire le richieste dei client anche se I server di backup sono tutti “down”. Infatti è possibile definire sugli oggetti in cache la “grace”, che rappresenta il periodo in cui un oggetto non deve essere refreshato e può essere restituito al client. Questo può essere compiuto scrivendo nel file di configurazione le seguenti righe:

sub vcl_recv {
            set req.grace = 6h;
}

impostando il parametro grace sulla richiesta in ingresso a 6 ore, ad esempio.

In conclusione, Varnish è un tool molto efficiente. Oltre ad aumentare le performance del tuo sito web può anche agire come full backup gestendo al meglio scenari di disaster recovery.