Progetto

Generale

Profilo

SupervisorPerDjango » Cronologia » Versione 2

Simone Piccardi, 11-12-2014 18:21

1 1 Mark Caglienzi
h1. Uso di Supervisor per controllare più istanze di Django
2
3
"Supervisor":http://supervisord.org è 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.
4
5
Per ogni approfondimento riguardo a supervisor, si rimanda alla "documentazione ufficiale":http://supervisord.org.
6
7
*NB*: Supervisor "non funziona con Python 3":http://supervisord.org/introduction.html#platform-requirements.
8
9
h2. Prerequisiti
10
11
* @# apt-get install supervisor@
12
* Progetto django in @/home/utente/projects/django/@
13
14
h2. Configurazione di supervisor
15
16
Debian installa supervisor e avvia il demone @supervisord@ con il file @/etc/supervisor/supervisord.conf@ che contiene queste direttive:
17
18
<pre>
19
; supervisor config file
20
21
[unix_http_server]
22
file=/var/run/supervisor.sock   ; (the path to the socket file)
23
chmod=0700                       ; sockef file mode (default 0700)
24
25
[supervisord]
26
logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)
27
pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
28
childlogdir=/var/log/supervisor            ; ('AUTO' child log dir, default $TEMP)
29
30
; the below section must remain in the config file for RPC
31
; (supervisorctl/web interface) to work, additional interfaces may be
32
; added by defining them in separate rpcinterface: sections
33
[rpcinterface:supervisor]
34
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
35
36
[supervisorctl]
37
serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL  for a unix socket
38
39
; The [include] section can just contain the "files" setting.  This
40
; setting can list multiple files (separated by whitespace or
41
; newlines).  It can also contain wildcards.  The filenames are
42
; interpreted as relative to this file.  Included files *cannot*
43
; include files themselves.
44
45
[include]
46
files = /etc/supervisor/conf.d/*.conf
47
</pre>
48
49
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).
50
51
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).
52
53
h3. Creazione del file @django.conf@
54
55
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":http://supervisord.org/configuration.html?highlight=python#configuration-file la pagina che spiega approfonditamente, con esempi, questa funzionalità).
56
Si crei il file @/etc/supervisor/conf.d/django.conf@ per la gestione delle istanze di django (in questo esempio si useranno i devserver):
57
58
<pre>
59
[program:django]
60
numprocs=4
61
directory=/home/utente/projects/django
62
command=python manage.py runserver 80%(process_num)02d
63
process_name=%(program_name)s_%(process_num)02d
64
user=utente
65
redirect_stderr=true
66
stdout_logfile=/home/utente/projects/django/supervisor_stdout_%(process_num)02d.log
67
stopsignal=KILL
68
stopasgroup=true
69
killasgroup=true
70
</pre>
71
72
La sezione @[program:django]@ contiene quindi le impostazioni di base per gestire 4 istanze di django. Le singole righe significano:
73
74
* Numero di processi da avviare.
75
* Directory in cui entrare prima di eseguire il comando.
76
* Comando da eseguire per ogni processo avviato (dato che @numprocs@ è stato specificato, ed è diverso da 1, bisogna che in @command@ sia presente @%(process_num)02d@ per differenziare le righe di comando). In questo esempio, con @numprocs@ che va da 0 a 3, verranno avviati 4 processi alle porte @8000@, @8001@, @8002@, @8003@.
77
* Nome del processo i-esimo. In questo esempio si chiameranno @django_00@, @django_01@, @django_02@, @django_03@.
78
* Utente da usare per lanciare i comandi. In questo esempio @supervisord@ tenta di passare all'utente @utente@, in modo da non lanciare i comandi come utente di @supervisord@ (che potrebbe essere @root@). Se questo tentativo fallisce, il comando non viene eseguito.
79
* Redirigere gli @stderr@ dei processi creati nei rispettivi @stdout@.
80
* File in cui loggare @stdout@.
81
* 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.
82
83
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....
84
85
h2. Uso di @supervisorctl@
86
87
Questo è un programma che può essere usato per inviare comandi una tantum:
88
89
<pre>
90
# supervisorctl start all
91
</pre>
92
93
oppure avviato senza parametri perché fornisca una shell da cui poter interrogare @supervisord@:
94
95
<pre>
96
# supervisorctl 
97
django:django_00                   RUNNING    pid 9633, uptime 0:41:34
98
django:django_01                   RUNNING    pid 9634, uptime 0:41:34
99
django:django_02                   RUNNING    pid 9648, uptime 0:41:33
100
django:django_03                   RUNNING    pid 9659, uptime 0:41:32
101
supervisor> help
102
103
default commands (type help <topic>):
104
=====================================
105
add    clear  fg        open  quit    remove  restart   start   stop  update 
106
avail  exit   maintail  pid   reload  reread  shutdown  status  tail  version
107
108
supervisor> stop all
109
django_00: stopped
110
django_01: stopped
111
django_02: stopped
112
django_03: stopped
113
supervisor> start all
114
django_00: started
115
django_01: started
116
django_02: started
117
django_03: started
118
</pre>
119
120
Come si vede qui è possibile interrogare il demone e vedere i processi attivi, fermarli, avviarli, ed è anche presente un help in linea.
121
122
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).
123 2 Simone Piccardi
124
125
h2. Impostazione di invio di email di avviso e di allarme via supervisor. 
126
127
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:
128
129
<pre>
130
easy_install superlance
131
</pre> 
132
133
che instellerà tutto il necessario, compresi gli script che ci interessano che verranno posti sotto @/usr/local/bin/@.
134
135
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:
136
137
<pre>
138
[eventlistener:crashmail]
139
command=/usr/local/bin/crashmail -a -m piccardi@truelite.it
140
events=PROCESS_STATE
141
</pre>
142
143
in questo caso in genere il servizio viene riavviato automaticamente da @supervisor@.
144
145
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:
146
147
<pre>
148
[eventlistener:fatalmailbatch]
149
command=/usr/local/bin/fatalmailbatch --toEmail="piccardi@truelite.it" --fromEmail="supervisor@truelite.it" --subject="Alarm for a fatal crash"
150
events=PROCESS_STATE,TICK_60
151
</pre>
152
153
Si possono ovviamente attivare entrambe le notifiche aggiungendo entrambe le sezioni indicate.