Uso di Supervisor per controllare più istanze di Django¶
Supervisor è presente in Debian, e permette il controllo (avvio, stop, riavvio automatico, logging, eccetera) di programmi che devono essere monitorati nel loro funzionamento. In questa guida si avvieranno e si gestiranno quattro istanze del devserver di un'applicazione Django in locale.
Per ogni approfondimento riguardo a supervisor, si rimanda alla documentazione ufficiale.
NB: Supervisor non funziona con Python 3.
Prerequisiti¶
# apt-get install supervisor
- Progetto django in
/home/utente/projects/django/
Configurazione di supervisor¶
Debian installa supervisor e avvia il demone supervisord
con il file /etc/supervisor/supervisord.conf
che contiene queste direttive:
; supervisor config file [unix_http_server] file=/var/run/supervisor.sock ; (the path to the socket file) chmod=0700 ; sockef file mode (default 0700) [supervisord] logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log) pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid) childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP) ; the below section must remain in the config file for RPC ; (supervisorctl/web interface) to work, additional interfaces may be ; added by defining them in separate rpcinterface: sections [rpcinterface:supervisor] supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface [supervisorctl] serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket ; The [include] section can just contain the "files" setting. This ; setting can list multiple files (separated by whitespace or ; newlines). It can also contain wildcards. The filenames are ; interpreted as relative to this file. Included files *cannot* ; include files themselves. [include] files = /etc/supervisor/conf.d/*.conf
e come si vede il demone risponde alla unix socket /var/run/supervisor.sock
, e supervisorctl
(software che presenta una shell di controllo) usa questa socket per inviare comandi al demone (che serviranno per monitorare, avviare, riavviare, fermare i servizi configurati).
Grazie alla direttiva [include]
supervisor carica file di configurazione aggiuntivi dalla directory /etc/supervisor/conf.d/
, quindi questo file può essere lasciato così (a meno di aver bisogno di settaggi particolari).
Creazione del file django.conf
¶
Come si vedrà, i file di configurazione di supervisor supportano la sintassi python per fare output di valori come se si scrivesse in una stringa (qui la pagina che spiega approfonditamente, con esempi, questa funzionalità).
Si crei il file /etc/supervisor/conf.d/django.conf
per la gestione delle istanze di django (in questo esempio si useranno i devserver):
[program:django] numprocs=4 directory=/home/utente/projects/django command=python manage.py runserver 80%(process_num)02d process_name=%(program_name)s_%(process_num)02d user=utente redirect_stderr=true stdout_logfile=/home/utente/projects/django/supervisor_stdout_%(process_num)02d.log stopsignal=KILL stopasgroup=true killasgroup=true
La sezione [program:django]
contiene quindi le impostazioni di base per gestire 4 istanze di django. Le singole righe significano:
- Numero di processi da avviare.
- Directory in cui entrare prima di eseguire il comando.
- Comando da eseguire per ogni processo avviato (dato che
numprocs
è stato specificato, ed è diverso da 1, bisogna che incommand
sia presente%(process_num)02d
per differenziare le righe di comando). In questo esempio, connumprocs
che va da 0 a 3, verranno avviati 4 processi alle porte8000
,8001
,8002
,8003
. - Nome del processo i-esimo. In questo esempio si chiameranno
django_00
,django_01
,django_02
,django_03
. - Utente da usare per lanciare i comandi. In questo esempio
supervisord
tenta di passare all'utenteutente
, in modo da non lanciare i comandi come utente disupervisord
(che potrebbe essereroot
). Se questo tentativo fallisce, il comando non viene eseguito. - Redirigere gli
stderr
dei processi creati nei rispettivistdout
. - File in cui loggare
stdout
. - Le ultime tre righe sono necessarie per far sì che
supervisord
riesca a killare correttamente i devserver di django senza lasciare processi orfani né bloccare le porte in caso di riavvio di un'istanza.
Di default i processi vengono avviati all'avvio di supervisord
, ma si può impedire (autostart=false
), si può richiedere che i processi siano sempre riavviati in caso di segnali di KILL
(autorestart
), si possono configurare i timeout di attesa quando un processo cambia stato, il tipi di exit code attesi per discriminare quando un processo esce correttamente o per qualche errore/malfunzionamento (exit_codes
), eccetera....
Uso di supervisorctl
¶
Questo è un programma che può essere usato per inviare comandi una tantum:
# supervisorctl start all
oppure avviato senza parametri perché fornisca una shell da cui poter interrogare supervisord
:
# supervisorctl django:django_00 RUNNING pid 9633, uptime 0:41:34 django:django_01 RUNNING pid 9634, uptime 0:41:34 django:django_02 RUNNING pid 9648, uptime 0:41:33 django:django_03 RUNNING pid 9659, uptime 0:41:32 supervisor> help default commands (type help <topic>): ===================================== add clear fg open quit remove restart start stop update avail exit maintail pid reload reread shutdown status tail version supervisor> stop all django_00: stopped django_01: stopped django_02: stopped django_03: stopped supervisor> start all django_00: started django_01: started django_02: started django_03: started
Come si vede qui è possibile interrogare il demone e vedere i processi attivi, fermarli, avviarli, ed è anche presente un help in linea.
Se supervisord
è stato avviato da root
, e nel file supervisord.conf
il setting chmod
è 0700, ovviamente un utente non privilegiato non potrà accedere alla socket di interrogazione, e supervisorctl
andrà lanciato da root
(come nell'esempio qui sopra).
Impostazione di invio di email di avviso e di allarme via supervisor.¶
Il pacchetto superlance
consente agganciare a supervisor
degli utili script che consentono di osservarne gli eventi per eseguire opportune azioni. Due di questi sono particolarmente utili, il primo per notificare crash di un servizio osservato, il secondo per avvisare di un servizio fermo per un fallimento fatale. Per poterlo utilizzare è anzitutto necessario installare il relativo pacchetto python con:
easy_install superlance
che instellerà tutto il necessario, compresi gli script che ci interessano che verranno posti sotto /usr/local/bin/
.
A questo punto basterà registrare sull'eventlistner di supervisor
i due script che ci interessano; il primo è crashmail
, che spedisce una email tutte le volte che un servizio esce inaspettatamente con un errore, contenente il nome del servizio e le relative informazioni, per questo basta aggiungere a /etc/supervisor/supervisord.conf
qualcosa del tipo:
[eventlistener:crashmail] command=/usr/local/bin/crashmail -a -m sviluppatore@dominio.it events=PROCESS_STATE
in questo caso in genere il servizio viene riavviato automaticamente da supervisor
.
Il secondo script, fatalmailbatch
, tiene invece sotto ossevazione gli eventi ed invia una email di allarme (su un periodo di un minuto) quando rileva che un servizio si ferma nello stato FATAL
, segno che supervisor
ha fallito nel tentativo di farlo ripartire, in questo caso occorre aggiungere a /etc/supervisor/supervisord.conf
qualcosa del tipo:
[eventlistener:fatalmailbatch] command=/usr/local/bin/fatalmailbatch --toEmail="sistemista@dominio.it" --fromEmail="supervisor@dominio.it" --subject="Alarm for a fatal crash" events=PROCESS_STATE,TICK_60
Si possono ovviamente attivare entrambe le notifiche aggiungendo entrambe le sezioni indicate.
Aggiornato da Simone Piccardi quasi 10 anni fa · 3 revisions