Web proxy con Lighttpd, Apache e mod_rpaf

Lighttpd + ApacheDi recente ho sperimentato delle ottimizzazioni su di un web server che ospita un portale ad alto traffico. L'architettura è una classica LAMP, con Apache e PHP compilati ad-hoc e un'installazione di Drupal pesantemente modificata ed estesa.
L'obiettivo era diminuire il carico generale del server a livello di cpu e memoria utilizzata.

Una soluzione interessante e dal risultato sorprendente è stata l'introduzione sulla stessa macchina di Lighttpd come proxy verso Apache.

Lighttpd è un web server relativamente giovane, forse poco diffuso ma molto interessante. Tra le caratteristiche spicca l'ottimizzazione per la velocità e l'utilizzo di memoria, oltre ad una struttura modulare che favorisce l'adattamento a molteplici scenari di utilizzo.

Per diversi motivi non è stato possibile sostituire completamente Apache con Lighttpd, perciò ho scelto di configurare Lighttpd come frontend, in ascolto quindi sulla porta 80, mentre Apache è stato spostato sulla 8080.
Inoltre usando la stessa directory root per entrambi i web server è possibile far servire alcuni URL a Lighhtpd ed altri ad Apache, ad esempio le immagini o altri contenuti statici al primo (generalmente molto più veloce) ed i contenuti dinamici al secondo.

Ecco parte del file di configurazione di Lighttpd:

# lighttpd.conf (estratto)
# abilitazione di alcuni moduli tra cui mod_proxy
server.modules = ( "mod_access", "mod_status", "mod_proxy", "mod_expire" ) # directory root server.document-root = "/var/www/html/miosito.it/" # porta server.port = 80 # configurazione proxy
# immagini servite da lighttpd, tutto il resto da apache
$HTTP["url"] !~ "(\.gif|\.png|\.jpg)$" { proxy.server = ( "" => ( ("host" => 192.168.0.1, "port" => 8080) ) ) }

 e questa è la configurazione di Apache, limitatamente alle opzioni di interesse:

# httpd.conf (estratto)
# directory root
DocumentRoot "/var/www/html/miosito.it" # porta Listen 8080 # nome server ServerName miosito.it:8080 # modulo rpaf LoadModule rpaf_module modules/mod_rpaf-2.0.so # opzioni modulo rpaf RPAFenable On RPAFsethostname On RPAFproxy_ips 192.168.0.1 127.0.0.1 RPAFheader X-Forwarded-For 

Tutto molto semplice. Rimane da spiegare solo l'utilizzo del modulo rpaf su Apache. Il motivo è presto detto: con una configurazione di questo tipo, tutte le richieste http che Lighttpd inoltra in quanto proxy ad Apache risultano provenienti dall'indirizzo IP locale (nell'esempio 192.168.0.1) e questo può essere un problema per determinate applicazioni web che necessitano di conoscere il reale indirizzo ip dei client, così come per il log degli accessi che perde di fatto l'informazione sulla provenienza.

Scartando il trucchetto che consiste, lato application server, nel sostituire alla variabile server "REMOTE_ADDR" il valore della cugina "HTTP_X_FORWARDED_FOR", un'interessante soluzione trasparente può essere l'uso del modulo aggiuntivo mod_rpaf per Apache.

rpaf è un modulo, scritto da Thomas Eibner, che sostituisce l'indirizzo del client con quello presente nell'header HTTP X-Forwarded-For (o altro configurabile), rendendolo così disponibile agli altri moduli ed alle applicazioni che girano su Apache. La versione per Apache 2.0 funziona bene anche sulla 2.2.

Scaricato, compilato, installato, riavviato Apache: si è presentato subito un problema, la sostituzione dell'indirizzo ip del client non aveva effetto a livello di direttive sui file .htaccess. Da una veloce ricerca in rete è emerso che il problema è noto e legato all'abilitazione di IPv6 sull'interfaccia di rete della macchina; ho scovato diverse patch e le ho applicate aggirando alcuni conflitti al file mod_rpaf-2.0.c della versione 0.6 in mio possesso. Ricompllato, reinstallato, riavviato Apache: tutto OK!
Il file sorgente è allegato in fondo all'articolo.

Risolto l'ostacolo, è tempo di valutazioni. Il risultato della nuova configurazione Lighttpd+Apache è stato ottimo sia a livello di performance che di alleggerimento del server:

  • la navigazione sul sito/portale risulta visivamente più veloce
  • le richieste http simultanee di Apache sono scese da 300 a 5
  • Lighttpd gestisce tranquillamente oltre 1500 http simultanee
  • il server load medio e l'utilizzo di memoria sono scesi significativamente
  • la capacità del server (in termini di utenti contemporanei) è aumentata notevolmente, a costo zero

Riassumendo la nuova configurazione presenta:

  • Lighttpd 1.4.18 come frontend
  • Apache 2.2.6 come backend
  • mod_rpaf 0.6 (patchato) aggiunto ad Apache

 

Finalmente!

Mi stavo convincendo di essere l'unico a utilizzare questo set-up: tutte le guide che ho trovato fanno il contrario e usano Apache come frontend e forwardano le richieste per i file statici a Lighttpd, il che mi sembra contrario a ogni logica!

Pesissimo

davide

ma cosa dici... è una

ma cosa dici... è una leggeressa... :-)