Progetto

Generale

Profilo

Configurare Apache/WSGI per Django e affini

L'uso di mod_wsgi per eseguire applicazione web in Python (prima fra tutte Django) può risultare molto problematico con la configurazione standard, dato che questa è pensata per applicazioni PHP e le modalità di funzionamento di quelle Phyton è totalmente diversa. Quanto indicato qui deriva dalle indicazioni date dall'autore di mod_wsgi (Graham Dumpleton, vedi http://www.slideshare.net/GrahamDumpleton/pycon-us-2013-making-apache-suck-less-for-hosting-python-web-applications).

In particolare dovendo caricare tutta l'applicazione in un colpo solo all'avvio, la creazione e distruzione di processi tipica dell'MPM prefork rischia di avere un impatto molto pesante sulle prestazioni. E' pertanto opportuno utilizzare sempre l'MPM worker, cosa che su Debian si fa installando:

apt-get install apache2-mpm-worker

Occorre inoltre una configurazione iniziale adeguata, dato che la memoria è condivisa infatti non conviene far partire troppi processi ed evitare di tenerne attivi troppi, in quanto l'occupazione di memoria verrà aumentata, in particolare poi è importante la direttiva MaxMemFree, che indica la quantità di memoria che il thread pool può allocare senza chiamare un free per liberare quella inusata. Questo su Apache 2.2 è illimitato, ma in realtà questa non serve ed è opportuna ridurla. Inoltre la creazione di processi nuovi, come accennato è onerosa per cui conviene tenerli al minimo.

Questo comporta modificare i default di /etc/apache2/apache2.conf, una scelta consigliata è la seguente, un cui, scelta l'unità base di 25 thread per processo (di cui si dovranno usare multipli), si parte da un minimo (MinSpareThreads) di 25, corrispondenti ad un processo attivo per lasciarne un massimo (MinSpareThreads) di 73, corrispondenti a tre processi, il numero massimo di processi viene fissato da MaxClients che con un valore di 100 (e l'equivalenza fra un client ed un thread) significa 4 processi massimo:

<IfModule mpm_worker_module>
        StartServers       2
        MinSpareThreads    25
        MaxSpareThreads    75
        ThreadLimit          64
        ThreadsPerChild      25
        MaxClients        100
        MaxRequestsPerChild   0
        MaxMemFree      256
</IfModule>

Ma la ottimizzazione principale si ottiene utilizzando mod_wsgi in modalità demone, in questo caso i processi dedicati vengono stabiliti direttamente dalle configurazioni relative al modulo, che li fa partire in maniera indipendente, con un numero fisso di processi e thread che rende le cose molto più prevedibili, i processi di apache in questo caso fanno da proxy verso i processi gestiti da mod_wsgi.
In tal caso questo deve essere fatto inserendo nel ''virtal host'' che gestisce ''django'' (o affine) le direttive:

        WSGIDaemonProcess nomeidentificativo processes=3 threads=25 display-name=%{GROUP}
        WSGIProcessGroup nomeidentificativo

che nel caso lancia 3 processi (direttiva processes che usano 25 thread ciascuno (direttiva threads), e imposta il nome dei processi (direttiva display-name) che verrà mostrato da ps nella forma standard a (wsgi:nomeidentificativo).