Pergunta

Eu tenho alguns servidores e outros daemons que eu preciso para começar-se na seqüência correta.

Eu criei init.d scripts no script de esqueleto, e pode instalá-los para começar em seqüência adequada usando o sistema de nomeação numeradas, mas algumas questões permanecem:

Um servidor ( 'serverA') precisa inicializar uma conexão banco de dados e, em seguida, escuta em um soquete. Outro servidor ( 'serverB'), então precisa se conectar a esse socket, e a conexão falhará se o processo anterior ainda não está escutando. Existe uma maneira de impedir que o script init.d para serverA de terminar até serverA começou a ouvir? Init serverB não será iniciado até que a inicialização serverA foi encerrado.

Agora, a configuração funciona por ter serverB apenas repetir a conexão até que tenha êxito, mas essa abordagem parece frágil. Eu gostaria de ter uma compreensão mais determinista de como forçar o sequenciamento.

Foi útil?

Solução

Sim, esta é a minha pergunta que eu estou respondendo, mas eu achei que esta técnica seja útil, e estou compartilhando por mais ninguém lutando com os problemas similares.

Eu encontrei socat ser muito útil na espera por uma porta ou socket. Um script init.d como:

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

irá aguardar até o soquete se torna gravável, em seguida, retornar. Não há daemonization envolvido, então ele bloqueia a execução de scripts init.d numerados mais elevados até que ele termine.

O uso de tais scripts garçom vai abrandar a seqüência de inicialização, e são, portanto, não ideal, mas são uma grande melhoria a partir da abordagem muito frágil da aspersão 'sono n' declarações nos scripts.

Outras dicas

Eu não acho que é frágil - pelo menos eu posso pensar em cenário de onde não será frágil. Tenha um tempo de repetição de 5 segundos e não é mau de todo. é uma abordagem Kiss e que não existem quaisquer casos de canto que você não entende.

Conseguir um ambiente distribuído sincronizado não é para os fracos de coração, e seu exagero no seu exemplo.

Para dar-lhe alguma confiança em sua abordagem que eu posso te dizer que eu tenho dezenas de processos de servidor complexas escritas à mão distribuídos ao longo de um web-fazenda, eles nunca me deu qualquer dor mesmo quando os servidores de banco de dados desapareceram, ou quando a rede troncos caíram etc. Eles simplesmente continuar correndo em modo degradado até que as bases de dados voltar.

Se o servidor escuta em um soquete de domínio, você poderia construir um circuito que as pesquisas para o socket. Pode haver uma maneira mais fácil de fazer isso em bash, mas poderia ser algo como:

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

Outra solução é ter o seu servidor não daemonize até que abriu o soquete de escuta. Dessa forma, o script de inicialização fará uma pausa até que os daemonizes processo, o que garante a tomada está disponível.

Claro, isso depende da sua aplicação fazendo a própria daemonization, em vez de através de outros meios. ( "/ Usr / bin / myserver &" ou algo semelhante.)

Atualização:

Observe também que, o que você está fazendo agora é tudo o init estilo System-V. Ubuntu realmente usa Upstart, que é um sistema baseado em eventos, em vez de uma seqüência de scripts. Você pode optar por usar empregos arrivista em vez de scripts de inicialização System-V, e disparar um Upstart evento personalizado do seu servidor, que irá desencadear o lançamento de seu segundo servidor.

O Guia de Primeiros Passos tem um exemplo desta na parte inferior. Eu não sei se há uma maneira API, mas que poderia ser apenas uma questão de um “sistema ( '/ bin / initctl emitem MyEvent');” no ponto certo no tempo em seu primeiro servidor. Alguém com mais experiência Upstart pode ser capaz de elaborar melhor / mais.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top