Domanda

Ho un paio di server e altri demoni di cui ho bisogno per avviare nella giusta sequenza.

ho creato gli script init.d dalla bozza di script, e può installarli per iniziare nella giusta sequenza usando il sistema di denominazione numerata, ma rimangono alcuni problemi:

Un server ( 'serverA') ha bisogno per inizializzare una connessione al database, e poi ascoltare su un socket. Un altro server ( 'serverB'), poi ha bisogno di connettersi a tale presa, e la connessione avrà esito negativo se il processo precedente non è ancora in ascolto. C'è un modo per evitare che lo script init.d per serverA di terminare fino serverA ha iniziato ad ascoltare? L'init serverB non comincerà fino a quando l'init serverA è terminato.

In questo momento, l'installazione funziona avendo serverB basta riprovare la connessione fino a quando non riesce, ma questo approccio sembra fragile. Vorrei una comprensione più deterministica di come forzare il sequenziamento.

È stato utile?

Soluzione

Sì, questa è la mia domanda che io rispondo, ma ho trovato questa tecnica per essere utile, e sto condividendo per chiunque altro alle prese con i problemi simili.

Ho trovato socat per essere molto utile in attesa di una presa di corrente o il porto. Uno script init.d come:

case “$1″ in
  start)
  echo '--benign phrase' | socat - UNIX-CONNECT:/path/to/socket,retry=10,intervall=1
;;

attenderà fino a quando la presa diventa scrivibile, per poi tornare. Non v'è alcun daemonization coinvolti, in modo blocca l'esecuzione di script init.d numero più alto fino a quando non finisce.

L'uso di tali script cameriere rallenterà la sequenza di avvio, e sono quindi non ottimale, ma sono un grande miglioramento da un approccio molto fragile di cospargere di sonno n 'dichiarazioni negli script.

Altri suggerimenti

Non credo che è fragile - almeno mi viene in mente lo scenario di cui non sarà fragile. Avere un numero di tentativi di 5 secondi e la sua non è affatto male. il suo un approccio bacio e non ci sono casi d'angolo, che non si capisce.

Ottenere un ambiente distribuito sincronizzato non è per i deboli di cuore, e il suo eccessivo nel tuo esempio.

Per darvi una certa fiducia nel vostro approccio vi posso dire che ho decine di processi server complessi scritte a mano distribuiti su un web-farm, non hanno mai mi ha dato alcun dolore, anche quando i server di database sono scomparsi, o quando la rete tronchi sono scesi ecc Essi semplicemente tenere in situazioni degradate fino alle basi di dati ritornano.

Se il server è in ascolto su un socket di dominio, si potrebbe costruire un ciclo che i sondaggi per il socket. Ci potrebbe essere un modo più semplice per fare questo in bash, ma potrebbe essere qualcosa di simile:

for i in 1 2 3 4 5; do
  if [ -e '/var/run/myserver.sock' ]; then
    break
  fi
done

Un'altra soluzione è quella di avere il server non demonizzare fino a quando non ha aperto il socket di ascolto. In questo modo, lo script di inizializzazione viene interrotta finché i daemonizes processo che garantisce la presa è disponibile.

Naturalmente, questo dipende dalla vostra applicazione facendo la daemonization in sé, piuttosto che attraverso altri mezzi. ( "/ Usr / bin / myserver &" o simili.)

Aggiornamento:

Si noti inoltre che, quello che state facendo ora è tutto init stile del System-V. Ubuntu utilizza effettivamente Upstart, che è un sistema basato sugli eventi, piuttosto che una sequenza di script. Si potrebbe optare per l'utilizzo di posti di lavoro upstart invece di script di inizializzazione del System-V, e sparare un evento Upstart personalizzato dal server, che attiverà il lancio del secondo server.

Il Guida introduttiva ha un esempio questo al fondo. Non so se c'è un modo API, ma potrebbe essere solo una questione di un “sistema ( '/ bin / initctl emettere MyEvent'),” al punto giusto in tempo nel vostro primo server. Qualcun altro con più esperienza Upstart può essere in grado di elaborare una migliore / più.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top