Apache performance tuning

Suggerimenti e informazioni per migliorare le performance di Apache.

Migliorare le prestazioni di Apache

Apache è stato sviluppato dando priorità alla stabilità, integrità e espandibilità del servizio mentre meno attenzione è stata data alla performance brutale, pur essendo stati fatti notevoli sforzi al riguardo, in particolare con la versione 2.0.
Per questo motivo, in performance test di laboratorio, Apache non risulta sempre la soluzione più veloce, anche se spesso, in condizioni e con necessità reali, le sue feature risultano di fatto più efficaci.

Esistono comunque diversi modi per migliorare le performance di Apache, fondamentalmente riguardano la configurazione e la quantità di features che si intendono utilizzare.

Restando inteso che il tuning del proprio sistema va fatta sulla base delle specifiche esigenze, per cui non è semplice dare indicazioni assolute, valide in ogni contesto, è possibile fornire dati utili su come configurare il proprio server per migliorarne le prestazioni, sia in termini di velocità che in termini di occupazione delle risorse del sistema e scalabilità.

In generale:
– Un Apache compilato staticamente, senza il supporto di moduli dinamici, risulta generalmente più efficiente. Gli stessi moduli da caricare dinamicamente (o da compilare staticamente) possono essere limitati e selezionati nel numero, a seconda delle direttive effettivamente utilizzate in modo da ridurre l’impronta in memoria del binario in esecuzione.
Uno strumento comodo per capire cosa effettivamente serve è server-info che indica quali direttive sono usate nel proprio file di configurazione e da quali moduli sono fornite.
– httpd.conf presenta una serie di direttive che riguardano esplicitamente le performance del sistema. Il loro tuning permette di adeguare meglio il proprio Web Server a situazioni di traffico diverse. Nel BOX dedicato si possono leggere i dettagli.
– Altre direttive influiscono in vario modo sulle performance, in particolare esistono direttive, presenti nel file di configurazione di default, che possono essere rimosse senza problemi perchè riguardano funzionalità che non vengono sfruttate sul proprio sistema.
– A livello di risorse hardware è la RAM quella che di fatto, come spesso accade, influisce maggiormente sulle performance. Su un server web performante non si dovrebbe mai utilizzare il file di SWAP, per cui ci si deve attrezzare per aumentare la memoria fisica.
– Nella maggior parte dei casi reali il vero collo di bottiglia di un sito web è la generazione dei contenuti dinamici. Spesso quindi il fine tuning di Apache ha un impatto trascurabile rispetto all’architettura generale del sito, agli Application Server e l’accesso al database di backend. In questi casi va spostata la propria attenzione sull’ottimizzazione del codice e delle query, l’indicizzazione delle tabelle del DB, la staticizzazione di parte dei contenuti dinamici.

Direttive che riguardano le performance

Vediamo alcune direttive di Apache che espressamente riguardano le performance e il dimensionamento di un server web.

GESTIONE DEI PROCESSI
Su Unix Apache 1.3 opera come un pre-forking server, dove un processo iniziale provvede a generare dei child che devono effettivamente gestire le richieste dei client.
Alcune direttive permettono di gestire il numero dei processi da aprire all’avvio e il quanti tenermi in standby, in attesa di richieste:
StartServers 5 – Imposta (di default a 5) il numero di processi figli che vengono laciati da Apache. Visto che la fase di forking di un nuovo figlio è onerosa in termini di risorse richieste, su siti ad alto traffico ha senso aumentare considerevolmente questo valore.
MinSpareServers 5 – Imposta (di default a 5) il numero minimo di child che devono essere sempre essere disponibili per gestire nuove richieste. Anche in questo caso su siti ad alto traffico e in particolare soggetti a picchi di attività, ha senso aumentare questo valore.
MaxSpareServers 10 – Imposta (di default a 10) il numero massimo di child che possono essere liberi in attesa di nuove richieste. Ovviamente questo valore ha senso se è superiore a MixSpareServers, ma non è il caso di impostarlo troppo alto, per non rischiare di avere un server che dopo un picco di attività, rimane con troppi processi figli inutilizzati.
MaxClients 256 – Imposta (di default a 256) il numero massimo di client che possono accedere contemporaneamente al server. Questo valore è piuttosto importante perchè di fatto limita il numero di utenti e permette di evitare che il server collassi sotto un carico troppo alto (a fronte di un messaggio di errore del tipo “Server Unavailable” ai client in eccesso). Va dimensionato secondo i limiti massimi gestibili dall’hardware: un valore troppo basso rischia di escludere, sotto carico, alcuni client che potrebbero essere serviti, un valore troppo alto rende il server soggetto al totale collasso.
E’ IMPORTANTE sottolineare che nei sorgenti e nei binari generalmente distribuibili, 256 è un limite massimo (a prescindere da quanto viene scritto nella configurazione). Per cui se si vuole avere un Apache in grado di gestire più di 256 client contemporaneamente si devono modificare i sorgenti, in particolare il file httpd.h, aumentare il valore associato alla voce HARD_SERVER_LIMIT e ricompilare il Apache.
MaxRequestsPerClient 0 – Imposta (di default a infinito, indicato con 0) il numero di richieste HTTP che ogni singolo processo di Apache deve gestire prima di essere terminato. Ha senso mettere un valore alto ma finito (esempio: 10000) per evitare potenziali memory leaks di un processo. In pratica, nel nostro esempio, dopo 10000 richieste gestite un child di Apache viene volontariamente terminato e sostituito da uno nuovo.

TUNING SU TCP/IP E HTTP
Alcune direttive di Apache influenzano il modo con cui il server utilizza i protocolli di rete su cui si basa.
SendBufferSize 32768 – Imposta, in byte, le dimensioni del buffer da allocare per gestire l’output da parte di ogni singolo child di Apache. Questo rende più efficiente il trasporto dei dati su TCP/IP in caso di latenze alte, ma aumenta l’occupazione di memoria (e può diventare critico sotto alto carico).
KeepAlive on – Permette al server di gestire più richieste HTTP fra uno specifico client e il child del server con cui comunica, utilizzando la stessa sessione TCP. Questo aumenta considerevolmente la velocità e l’ottimizzazione della gestione delle richieste, in quanto non richiede una nuova fase syn-synack per ogni GET del client. Su browser vecchi, che non supportano HTTP/1.1, questa opzione non funziona e può creare problemi (nella configurazione di default di Apache, con la direttiva BrowserMatch, si corregge il comportamente del server quando ha a che fare con questi client obsoleti).
KeepAliveTimeout 15 – Imposta il numero di secondi che un child di Apache aspetta senza ricevere nuove richieste dal client con cui sta comunicando prima di chiudere la connessione e tornare IDLE.
Su server sotto alto carico, questo valore è meglio che sia basso (intorno ai 15 secondi indicati) per evitare di occupare inutilmente risorse per troppo tempo.
MaxKeepAliveRequests 100 – Imposta il numero massimo di richeste che Apache può servire sulla stessa connessione. E’ bene impostare un valore finito e non esageratamente alto. Un valore troppo basso, di fatto, rende inutile il KeepAlive.
TimeOut 300 – Imposta il tempo in secondi (300 il valore di default) di inattività in generale, prima di terminare una connessione HTTP. Un valore troppo basso rischia di impedire il POST di grosse quantità di dati su link lenti, un valore troppo alto aumenta l’esposizione del server a DOS attack e ne sfrutta male le risorse.
ListenBacklog 511 – Imposta il numero di richieste da mettere in code quando Apache è troppo occupato per gestirle tutte. Con questa direttiva Apache imposta la lunghezza della coda e invece di droppare le richieste eccedenti, le processa appena possibile. Il valore di default è 511, non è il caso di aumentarlo troppo perchè è probabile che client messi in coda, dopo un certo tempo di mancata risposta da parte del server, abbiano già dirottato altrove le loro richieste.

Ottimizzazione della configurazione di Apache

Apache prevede nel file di configurazione di default una serie di direttive (alcune soltanto commentate) che da un lato ne aumentano le proprietà e le funzionalità, dall’altro impattano in modo  non trascurabile sulle performance del sistema.
Alcune di queste impostazioni possono essere necessarie per il nostro servizio e non se ne può prescindere, altre, spesso, risultano di fatto inutilizzate ed inutilmente configurate.
Vediamo alcuni casi.

REVERSE DNS LOOKUP DEI CLIENT
Ogni richiesta HTTP che arriva al server viene fatta da un HOST in rete con un proprio indirizzo IP che viene loggato da Apache. E’ possibile scegliere se provare anche a loggare il nome dell’host completo invece dell’IP, facendo una apposita query DNS (un REVERSE LOOKUP, che da un IP cerca di ottenere il rispettivo hostname). Assicurarsi che questa funzionalità venga disattivata e che Apache non perda tempo a risolvere gli indirizzi IP:
HostNameLookup off
Esistono svariati e migliori modi per procedere alla risoluzione degli IP loggati da Apache in un tempo successivo per dare statistiche sul traffico Web indicative si domini da cui arrivano i client.

GESTIONE DEI SYMLINK
Con la direttiva Options si può istruire Apache su come gestire i link simbolici.
Si può impedirgli di seguirli al di fuori della sua DocumentRoot o gli si può forzare un controllo sull’owner del link. Si risparmiano chiamate di sistema aggiuntive, e cicli di clock, se si evita ad Apache l’onere di controllare se un file è un link simbolico o no e, ancor più, di verificare il suo owner.
In termini di performance quindi la migliore scelta per qualsiasi container è :
Options FollowSymLinks che dice ad Apache di seguire i symlink e di non stare a controllarne l’owner.
Considerare che questa direttiva (insieme a Options SymLinksIfOwnerMatch) hanno una loro ragione d’essere in termini di sicurezza, per cui, come spesso accade, va valutato il giusto compromesso.

GESTIONE DEGLI OVERRIDE
La direttiva AllowOverride permette di definire in file separati (.htaccess) delle configurazioni specifiche per le directory in cui si trovano e in quelle figlie. In termini di performance l’abilitazione dell’Override comporta da parte di Apache una serie di controlli sull’esistenza effettiva del file .htaccess che inevitabilmente impattano sulle prestazioni. Per questo motivo, salvo eventualmente le directory in cui è strattamente necessario, si consiglia vigorosamente di disattivare l’override della configurazione generale con file locali .htaccess:
<Directory/>
AllowOverride None
</Directory>

Questo, per una volta, da benefici anche in termini di sicurezza.
Disattivando gli override diventa pleonastica anche la seguente parte di configurazione, presente negli httpd di default, che quindi può essere commentata:
#AccessFileName .htaccess

#<Files ~ "^\.ht">
#    Order allow,deny
#    Deny from all
#    Satisfy All
#</Files>

STATUS E EXTENDED STATUS
Il mod_status fornisce un utile strumento di diagnostica, la location /server-status consultabile per visualizzare in tempo reale lo stato delle connessioni al server web. Con la direttiva ExtendedStatus, inoltre, è possibile visualizzare  ulteriori interessanti informazioni.
Inutile dire che anche queste funzionalità impattano sulle risorse del sistema, in particolare l’ExtendedStatus, per cui, salvo necessità specifiche è bene disattivarle. Nel httpd.conf di default sono già scommentati:
#<Location /server-status>
#    SetHandler server-status
#    Order deny,allow
#    Deny from all
#    Allow from .your-domain.com
#</Location>
#ExtendedStatus On

COOKIE E SESSION TRACKING
Tracciare le sessioni di navigazione degli utenti tramite cookie o altri strumenti può essere comodo per l’analisi dei log o fondamentale per il corretto funzionamento di certi siti dinamici, ma se non serve è bene farne a meno, disattivando direttamente il relativo modulo:
#LoadModule usertrack_module   lib/apache/mod_usertrack.so
#AddModule mod_usertrack.c

Di fatto, anche caricando questo modulo, Apache non setta cookie a meno che non si indichino le specifiche direttive (  CookieDomain, CookieExpires, CookieName …)

CONTENT NEGOTIATION
In genere, la documentazione di Apache suggerisce che i vantaggi di poter gestire la content negotiation prevalgono sui benefici in termini di prestazioni che si hanno disattivandola.
Un eccezzione è la direttiva DirectoryIndex, che accetta anche nomi di file senza suffissi (es: DirectoryIndex index) ma che è preferibile definire per ogni file che si vuole utilizzare come home page:
DirectoryIndex index.php index.htm index.html index.cgi

LIMITAZIONE DEL LOGGING
Di default Apache logga ogni richiesta ricevuta per cui scrive, per ogni file servito, almeno una riga di log in un file aperta del proprio file system. In server particolarmente affollati questa operazione può determinare un ulteriore appesantimento del sistema (oltre che enormi file di log difficili da gestire).
L’access log può essere completamente disattivato oppure limitato alle sole richieste di pagine (senza appesantirlo con il logging delle GET a immagini e altri file collaterali), l’error log, che non può essere disattivato, può essere impostato per abbassare il numero di informazioni da loggare:
LogLevel error (di default è “warn).
Per disabilitare l’access loggin basta commentare ogni direttiva CustomLog o TransferLog:
# CustomLog /var/log/httpd/access_log common

RIMOZIONE DI MODULI INUTILIZZATI
La configurazione di Apache permette, tramite la funzione IfModule, di attivare una serie di direttive soltanto se il modulo che le fornisce è presente. In questo modo è possibile testare le funzionalità del web server, attivando o disattivando intere sezioni di configurazione, semplicemente commentando la riga che carica il relativo modulo:
#LoadModule perl_module modules/libperl.so
Inoltre, aiutandosi con le informazioni fornite da server-info, è possibile rimuovere direttamente i moduli che forniscono direttive che non vengono nemmeno considerate.
Per migliorare le prestazioni e diminuire l’occupazione di memoria di Apache, si può evitare di caricare tutti i moduli che non servono sia perchè non si utilizzano per niente le relative direttive, sia perchè si decide di rinunciare alle funzionalità offerte da direttive incluse in un container IfModule.


Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

 
%d blogger hanno fatto clic su Mi Piace per questo: