Velocizzazione dei siti: creare un fake CDN

Da un po’ di tempo mi è venuta in mente un’idea malsana per velocizzare il caricamento delle pagine web da parte dei browser, in particolare quelle che inducono il browser a scaricare tante risorse, per esempio immagini.

Warp speedAlla base di tutto c’è la considerazione che i browser decidono di scaricare in parallelo solo un numero limitato di risorse ospitate sullo stesso host.

Per esempio, se una pagina web contiene molte immagini e se tutte sono ospitate sotto l’host www.nomesito.it, allora i browser decideranno di scaricarne in parallelo solo una quantità massima, iniziando a richiedere le immagini successive via via che le immagini del primo “pool” sono state ricevute.

Una tecnica per indurre i browser a mettere in parallelo più richieste, ottimizzando così l’uso della banda, consiste nell’ospitare le immagini/risorse su host diversi.

Quella che segue è la tecnica che vi propongo. Sì, so che è improprio parlare di “CDN”. Un vero CDN è tutt’altra cosa. Non mi è venuto in mente un nome migliore di “Fake CDN”. Rassegnamoci.

Attenzione, pericolo: quanto segue non è un tutorial! Io vi indico il risultato finale che bisogna ottenere, sta a voi capire in che modo ottenerlo sul vostro specifico sito o server! Fate conto che diversi CMS (es: WordPress) o pannelli di controllo (es: Plesk) possono gestire in automatico alcuni file di configurazione dei vostri server e che ciò potrebbe andare in conflitto con eventuali modifiche manuali che voi decideste di fare. Procedete solo se sapete bene dove mettere le mani.

Cosa serve

  • Possibilità di gestire i DNS
  • Server Apache e possibilità di aggiungere alias ai domini serviti
  • Un linguaggio di programmazione lato server (PHP, ASPX, ecc.) che gestisca la produzione del codice HTML delle pagine
  • Saper programmare col linguaggio di programmazione

Primo passo

Bisogna modificare il DNS e inserire un host catch-all con un wildcard, per esempio: *.cdn.nomesito.it

Come tipo di record DNS potete usare un CNAME e potete farlo puntare al dominio principale nomesito.it

In questo modo tutti gli host del tipo qualsiasicosa.cdn.nomesito.it verranno risolti, alla fine dei giochi, con l’IP associato al nome di dominio nomesito.it

Secondo passo

Bisogna dire ad Apache che gli host del tipo *.cdn.nomesito.it devono essere gestiti come se fossero alias del dominio principale.

La direttiva da usare per ottenere ciò è ServerAlias, che dovrebbe essere inserita all’interno di una sezione VirtualHost già esistente nel vostro file di configurazione del server.

Alla fine dovreste avere qualcosa di simile:

<VirtualHost *:80>
    DocumentRoot /www/dominio.it
    ServerName www.dominio.it
    ServerAlias *.cdn.dominio.it
    ...
</VirtualHost>

Terzo passo

Il CMS del vostro sito dovrebbe essere istruito per produrre dinamicamente gli URL delle immagini usati negli attributi SRC dei tag IMG nelle pagine HTML.

Per esempio, ogni volta che c’è da produrre l’URL di una delle tante foto/immagini che ingolfano la vostra bellissima home page, il CMS dovrebbe produrre URL di immagine del tipo: http://a.cdn.nomesito.it/img/foto-322.jpg

Il sistema di parallelizzazione si ottiene usando, sulla stessa pagina, URL che fanno riferimento ad host diversi, tipo:

  • http://a.cdn.nomesito.it/img/foto-322.jpg
  • http://b.cdn.nomesito.it/img/foto-839.jpg
  • http://c.cdn.nomesito.it/img/foto-063.jpg
  • ecc…

In altre parole, la cartella “img” è sempre la stessa ma grazie ai tre passi indicati i suoi contenuti possono essere raggiunti attraverso host diversi.

Che criterio va usato per produrre la parte di host che deve variare per ogni URL di immagine (“a”, “b”, “c”, ecc.)? E’ categorico che ogni immagine venga mostrata sempre sotto lo stesso host, per evitare problemi di duplicazione di contenuti negli indici dei motori.

Il metodo più semplice per ottenere ciò potrebbe essere quello di calcolare un hash del nome immagine (es: foto-275.jpg), prendere il primo carattere della stringa dell’hash ed usarlo come lettera da anteporre a cdn.nomesito.it

Se come algoritmo di hash decideste di usare un CRC32, che produce un valore in esadecimale, i caratteri pseudo-random prodotti sarebbero le lettere dell’alfabeto da “a” ad “f” e i caratteri numerici da “0” a “9”: 16 diversi caratteri/host da usare per le vostre immagini.

Vi invito tuttavia a ideare sistemi differenti e più elastici per la generazione del carattere da anteporre a “cdn”, in quanto sedici differenti host potrebbero in alcuni casi anche essere eccessivi per i nostri scopi.

Conclusioni

L’esempio presentato si riferisce solo alle immagini, ma ovviamente può essere applicato a qualsiasi tipo di risorsa.

Questo post ha solo lo scopo di illustrare l’idea, sta a voi decidere come implementarla sui vostri sistemi: le modalità possono cambiare tantissimo. Se avete poco chiaro come procedere, è un buon segno per far fare il lavoro a qualcun altro. 😛

Buono smanettamento e, se vi va, fatemi sapere come è migliorata la parallelizzazione delle vostre risorse usando WebPageTest. 🙂

6 Responses to Velocizzazione dei siti: creare un fake CDN

  1. DonClaudissimo scrive il 27 June 2011 at 10:02

    Avevo intuito il tuo lavoro da un Tweet… aprezzo che l’incontro dell’altra sera abbia stimolato la tua voglia di testare 🙂 e sicuramente a me di provare a farlo 😀
    Non mi rimane di metterlo in pratica e farti sapere 😉
    Un saluto dal DON

  2. Andrea scrive il 27 June 2011 at 10:08

    Ciao Enrico,
    io utilizzo già da tempo la tecnica di cui hai parlato nell’articolo. Vorrei solo aggiungere che bisogna testare empiricamente i benefici ottenibili dalla ripartizione dei files su più fake cdn. Non sempre infatti “di più è meglio”.
    Per esperienza personale ho visto che che i benefici maggiori si ottengono utilizzando 3 o al max 4 fake. Ogni dominio di 3° o 4° livello implica una richiesta aggiuntiva per la risoluzione del nome in indirizzo ip per cui c’è anche il rischio di fare peggio. Inoltre il risultato varia a seconda del browser (e delle versioni) per cui soprattutto con le versioni vecchie di internet explorer (<=8) è meglio non esagerare con le parallelizzazioni.

    • LowLevel scrive il 27 June 2011 at 12:32

      Ciao Andrea, grazie mille per il contributo. 🙂

      Intuitivamente, nell’articolo avevo scritto di ideare sistemi migliori per la generazione degli host proprio per evitare una quantità eccessiva e la tua indicazione sul testare empiricamente i risultati ottenuti è sacrosanta.

      Già che ci sono, ti chiedo se sai come avviene il caching dei DNS da parte dei sistemi operativi. In particolare mi interesserebbe sapere se di fronte ad un record CNAME con wildcard, la richiesta di resolve viene eseguita internamente dal S.O. stesso (grazie alla cache del record DNS) oppure se viene comunque veicolata ad un DNS server esterno alla rete locale.

  3. Andrea scrive il 27 June 2011 at 13:38

    Credo che il dns resolve avvenga a livello di browser prima che a livello di SO. Inoltre viene seguito il dns solving per ogni dominio indipendentemente dal wildcard.
    Nei server in cui hi impostato il record * vedo che Firefox ad esempio esegue una resolve per ogni nome trovato. Ho tracciato questa cosa con Firebug e te ne accorgi anche con uno sniffer tipo Fiddler.
    Firefox (e credo anche gli altri non MS) ha un’interessante funzione di pre-fetch degli indirizzi in modo da velocizzare il caricamento delle pagine.
    E’ possibile abilitare il prefetching tramite meta tag: oppure specificando: . In questo modo si forza il browser a risolvere l’indirizzo e a tenerlo in memoria x utilizzi successivi… Può essere utile inserirlo nell’homepage. Come sempre bisogna testare il comportamento con i vari browser 😉

    • LowLevel scrive il 27 June 2011 at 14:01

      Grazie mille per le dritte! Proverò ad usare Wireshark per dare un’occhiata a chi realmente risponde alla richieste di resolve fatte dai browser nel caso di un record DNS con wildcard. 🙂

  4. Andrea scrive il 27 June 2011 at 14:04

    E’ un piacere :-). Completo il commento sopra postando questi 2 link di approfondimento relativi al prefetching di firefox e chrome: http://bitsup.blogspot.com/2008/11/dns-prefetching-for-firefox.html

    http://blog.chromium.org/2008/09/dns-prefetching-or-pre-resolving.html

Leave a Reply

Your email address will not be published. Required fields are marked *

More in Ideas
Hacking di Google: servizi nascosti, sconosciuti o futuri

Tutto quanto state per leggere è solo un gioco. Smanettare nel codice di Google è sempre divertente. Osservando il codice...

Close