SupervisorPerDjango » Cronologia » Versione 1
Mark Caglienzi, 13-12-2013 17:47
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). |