Compago

...free knowledge

 
  • Increase font size
  • Default font size
  • Decrease font size
Home Manuali Linux Tecniche di cache su un web server per ottimizzare il trasferimento dei dati

Tecniche di cache su un web server per ottimizzare il trasferimento dei dati

E-mail Stampa PDF

Tecniche di cache per risparmiare banda nella connessione

In questo articolo parleremo di come configurare un server Apache affinché non venga sprecata la banda della nostra connessione con la trasmissione superflua di dati.

Per capire meglio il problema potremo immaginare un sito web che ospita un video in formato flash; un utente che accede per la prima volta scaricherà il video e potrà vederlo nel suo pc. Se il giorno successivo volesse rivedere lo stesso video dovrebbe scaricarlo di nuovo!
Sebbene questo comportamento sia in tanti casi desiderato dal webmaster, in generale, se alcune parti del sito web, quali immagini, file multimediali e scripts, venissero conservate sul pc dell'utente per un tempo prestabilito, allora l'utente avrebbe un servizio più efficiente perché visiterebbe un sito web più veloce e il server che ospita il sito non verrebbe sovra caricato di lavoro inutile.

La soluzione a questi problemi solo le tecniche di cache control, e con questo termine mi riferisco precisamente ai vari modi che hanno come fine quello di evitare la trasmissione dei dati, e non a quelli che invece si limitano a evitare l'elaborazione delle pagine web da parte del server.

Quello che serve sta nel meccanismo di cache control del protocollo HTTP/1.1 (vedi  RFC 2616 sezione 14.9) ovvero il comportamento dal parte del server e del browser tramite il campo Cache-Control dell'intestazione del messaggio.
In pratica quando il browser effettua una richiesta al server per un particolare contenuto il server risponde con un messaggio la cui intestazione (header) ha alcuni campi, tra i quali c'è proprio quello chiamato Cache-Control, il quale può contenere i seguenti valori:

  • public - indica che la risposta autenticata deve essere conservata nella cache normalmente, altrimenti, se l'autenticazione era stata richiesta, verrà conservata nella cache privata.
  • private - indica che la cache deve essere conservata specificamente per ogni utente, e la cache non può essere condivisa.
  • no-cache - forza il browser a rivolgersi al server per la validazione del contenuto.
  • no-store - indica al browser di non conservare in alcuna forma il contenuto della richiesta
  • no-transform - indica che il contenuto non deve essere modificato. Questo campo è utile sopratutto se si ha a che fare con un proxy, dato che quest'ultimo potrebbe modificare il contenuto, ad esempio per ottimizzare le dimensioni o il formato di una immagine.
  • must-revalidate - obbliga il browser a convalidare la cache conservata indipendentemente da altre condizioni.
  • proxy-revalidate - simile alla precedente solo che non si applica alla cache non condivisa
  • max-age=(secondi) - specifica il numero di secondi dalla richiesta dopi i quali il contenuto deve essere considerato obsoleto
  • s-maxage=(secondi) - simile a max-age solo che si riferisce solo alla cache condivisa
  • cache-extension -

Se il server ad una richiesta risponde con un messaggio con il campo "Cache-Control = public,max-age=172800" vuol dire che il browser dovrebbe conservare il file nella cache condivisa (public) per 172800 secondi, cioè 2 giorni.

Per esempio una immagine di sfondo è bene che venga conservata dal client in modo che non debba essere scaricata più volte.

Se invece avesse risposto con un valore del tipo"private, no-store, no-cache, must-revalidate" avrebbe comunicato al browser di non conservare in alcun modo il file richiesto. Questo comportamento è molto comune per i contenuti dinamici, per cui conservare una copia di una pagina generata a seconda dell'utente o di alcuni parametri non avrebbe alcun senso.

Il campo Cache-Control è stato introdotto con il protocollo HTTP/1.1 mentre prima, nel protocollo HTTP/1.0, si usava il campo Pragma, per cui, se non si voleva mantenere il file, bastava impostare il campo sul valore "no-cache". Quindi per compatibilità sarà bene impostare anche questo campo.

Un altro campo che influisce sulla cache del browser è il campo Expires, che indica la data di scadenza dopo la quale il file richiesto deve essere considerato vecchio e quindi non più valido. Se però questa dichiarazione viene usata insieme a quella di Cache-Control allora quest'ultima sovrascriverà quella di Expires.

 

Pratica

Vediamo ora come mettere il pratica tutto quello visto fino ad ora. Quello che dovremo fare è modificare la configurazione del server apache in modo che a seconda della richiesta ricevuta, esso risponda in modo diverso a seconda del tipo di file richiesto.

Premetto che le seguenti dichiarazioni possono essere incluse nel file di configurazione generale oppure in a livello di virtualhost a seconda che le seguenti regole debbano essere valide per tutti i siti web contenuti nel server oppure debbano valere solo per alcuni di essi.

Innanzitutto per poter modificare l'header potremo utilizzare 2 metodi, il primo usa il modulo headers e serve a modificare l'intestazione del messaggio in maniera diretta, il secondo invece usa il modulo expires e viene usato esclusivamente per impostare i valori del campo Expires e automaticamente impostare il valore di max-age.

Nel primo caso occorrerà abilitare il modulo headers:

sudo a2enmod headers

nel secondo occorrerà abilitare il modulo expires:

sudo a2enmod expires

in entrambi i casi dovrete riavviare il server affinchè le modifiche abbiano effetto:

sudo /etc/init.d/apache2 restart

Ora occorre modificare la configurazione di Apache, nel mio caso sarà un virtualhost e verrà imposto che per le richieste dei file con estesione .ico, .jpg e .swf il campo Cache-Controll venga impostato a 2 giorni:

<VirtualHost *>
 ServerName test.miosito.com
 DocumentRoot /var/www/miosito
 <Directory /var/www/miosito>
 allow from all
 DirectoryIndex index.htm index.html index.php
 Options +Indexes
 <FilesMatch "\.(ico|swf|jpg)$">
   Header set Cache-Control "max-age=172800, public"
   Header set Expires "Tue, 09 Oct 2012 20:05:09 GMT"
 </FilesMatch>
</Directory>

In questo caso è stata usata la direttiva FilesMatch per selezionare il tipo di file ai quali vogliamo modificare l'header; successivamente sono stati impostati i valori di Cache-Control e di Expires. Comunque appare evidente la difficoltà nell'impostazione del campo di scadenza, il quale essendo una data ben precisa, deve essere calcolato di volta in volta, per cui molte volte chi usa questo metodo preferisce non impostare la scadenza, che tra l'altro deve essere in formato HTTP-date (vedi RFC 1123).

Per questo motivo suggerisco di usare il modulo expires per Apache, il quale permette l'impostazione della scadenza in maniera più semplice e calcola in automatico la max-age corrispondente, semplificando di molto il vostro compito.

Dopo aver installato il modulo expires avremo tre direttive a nostra disposizione:

  • La prima è l' ExpiresActive che può avere come valori on oppure off e serve per abilitare o disabilitare la generazione del campo expire negli header dei messaggi di risposta.
  • La seconda è l' ExpiresDefault con la quale si imposta la scadenza desiderata per tutti i tipi di file.
  • La terza è l' ExpiresByType che serve ad impostare la scadenza dei file a seconda del tipo.

Il bello di queste direttive è che la sintassi con cui si imposta la data di scadenza è molto flessibile e facile da leggere:

 ExpiresDefault "<base> [plus] {<num> <type>}*"
 ExpiresByType type/encoding "<base> [plus] {<num> <type>}*" 

Il primo valore da inserire è la base che può essere :

  • access (dal momento in cui il client ha fatto la richiesta)
  • now (equivalente a 'access')
  • modification (dall'ultima modifica del file)

naturalmente la direttiva che usa modification come base si applica solo alle richieste relative a file su disco, cioè ai file di cui il web server può leggere la data di modifica.
La restante sintassi comprende esplicitamente il numero di secondi, minuti, ore, giorni, settimane, mesi o anni dopo i quali il contenuto deve essere considerato scaduto. Esempio:

 ExpiresDefault "access plus 1 month 15 days 2 hours" 

Indica che il contenuto deve essere considerato scaduto dopo un mese, quindici giorni e due ore dal momento in cui il browser lo ha richiesto per la prima volta.

Con la direttiva ExpiresByType deve essere specificato anche il MIME-type del contenuto a cui applicare la regola:

 ExpiresByType text/html "access plus 1 month 15 days 2 hours"
 ExpiresByType image/gif "modification plus 5 hours 3 minutes" 

Un altro modo per specificare la data di scadenza è quello di usare il numero di secondi preceduto da una "A" in caso si voglia indicare il tempo relativo all'accesso al file oppure una "M" nel caso la base è la sua data di modifica:

# enable expirations
ExpiresActive On
# expire GIF images after a month in the client's cache
ExpiresByType image/gif A2592000
# HTML documents are good for a week from the time they were changed
ExpiresByType text/html M604800

Lo stesso virtualhost precedente usando il modulo expires, con una scadenza ad un anno, diventa:

<VirtualHost *>
 ServerName test.miosito.com
 DocumentRoot /var/www/miosito
 <Directory /var/www/miosito>
 allow from all
 DirectoryIndex index.htm index.html index.php
 Options +Indexes
 ExpiresActive On
 ExpiresByType application/x-shockwave-flash "access plus 1 year"
 ExpiresByType image/jpeg "access plus 1 year"
 ExpiresByType image/ico "access plus 1 year"
</Directory>

Per maggiori dettagli leggete la documentazione ufficiale relativa al modulo expires.

Queste direttive possono essere anche inserite in file .htaccess, ma attenzione che i file presi in considerazione a quel punto sarebbero solo quelli inclusi nella stessa directory del file .htaccess stesso.

Ultimo aggiornamento ( Giovedì 24 Novembre 2011 09:42 )  
Loading

Login