2013-07-03 18 views
19

ho [program:A], [program:B] nel mio supervisord.confpitone programma supervisord dipendenza

B dipendono A, significa:

A dovrebbe iniziare prima B.

Come garantire questo dal supervisore?

+0

potrebbe essere degno dare un'occhiata a [ordered-startup-supervisord] (https://pypi.python.org/pypi/ordered-startup-supervisord/) –

risposta

16

supervisord non supporta direttamente le dipendenze. Le opzioni disponibili sono:

  • Utilizzare le priorità. Impostare priority per A su un valore basso e verrà avviato prima di B e verrà chiuso dopo B. Il valore predefinito per priority è 999.

    Se si mettono i due programmi in un gruppo, ciò consente di avviarli e fermarli in tandem, con le priorità che regolano il loro ordine di avvio e arresto.

  • Scrivi un event listener che attende PROCESS_STATESTARTING -a- RUNNING transizione e STOPPING eventi per A, quindi istruire supervisord per avviare ed arrestare B in base a tali eventi. Avvia l'avvio automatico A, ma disabilita l'avvio automatico per B, in modo che il gestore eventi lo controlli.

+5

La mia comprensione è che l'approccio "prioritario" sopra molto probabilmente non funzionerà come previsto. Supervisord inizierà effettivamente i processi in ordine, ma ad es. [non aspetterà che il processo A sia completamente avviato prima di iniziare il processo B] (https://github.com/Supervisor/supervisor/issues/122) (cioè, supervisord ignorerà il parametro 'startsecs'). Invece, lancerà B immediatamente dopo A, che in molti casi non sarà (abbastanza) quello che vuoi. Questo comportamento [era già stato segnalato nel 2012 ma non è ancora stato fissato a partire dal 2014] (https://github.com/Supervisor/supervisor/issues/122). –

+0

@miguno: quindi l'opzione è utilizzare un listener di eventi. –

5

Se si vuole prendere una scorciatoia, e saltare la lettura della documentazione su event listeners e saltare la modifica dei programmi in modo da capire gli eventi, quindi:

Invece di iniziare il programma B (che dipende A) direttamente , è possibile avviare uno script Bash che va in stand-by fino al momento in cui è stato avviato A, quindi viene avviato B. Ad esempio, se si dispone di un database PostgreSQL e un server che non dovrebbe iniziare prima di PostgreSQL:

[program:server] 
autorestart=true 
command=/.../start-server.sh 

[program:postgres] 
user=postgres 
autorestart=true 
command=/usr/lib/postgresql/9.3/bin/postgres ... 

E poi dentro start-server.sh:

#!/bin/bash 

# Wait until PostgreSQL started and listens on port 5432. 
while [ -z "`netstat -tln | grep 5432`" ]; do 
    echo 'Waiting for PostgreSQL to start ...' 
    sleep 1 
done 
echo 'PostgreSQL started.' 

# Start server. 
echo 'Starting server...' 
/.../really-start-the-server 
2

this è una grande soluzione per me!

Una soluzione che ho usato è quello di impostare autostart=false sulle processi, quindi creare uno script bootstrap con autostart=true e autorestart=false (un one-shot). Il bootstrap può essere uno script di shell che chiama supervisorctl start per ogni processo. supervisorctl start bloccherà fino a quando un processo è stato avviato correttamente.

1

Una soluzione è utilizzare supervisorctl: imposta autostart su false per il programma B e nel programma lanciato da A, scrivere supervisorctl start B.

Esempio:

supervisor.cfg:

[supervisord] 
nodaemon=false 
pidfile=/tmp/supervisor.pid 
logfile=/logs/supervisor.log 

[unix_http_server] 
file=/var/run/supervisor.sock 

[rpcinterface:supervisor] 
supervisor.rpcinterface_factory=supervisor.rpcinterface:make_main_rpcinterface 

[supervisorctl] 
serverurl=unix:///var/run/supervisor.sock 

[program:A] 
command=do_a 

[program:B] 
command=do_b 
autostart=false 

Il programma do_a contiene:

#!/bin/bash 
#do things 
supervisorctl start B 

TBH è la soluzione suggerita da @drrzmr ma non ho capito in quel momento.