Como reiniciar automaticamente um serviço em caso de falha no Linux

23

No Windows, você pode definir o que deve acontecer se / quando um serviço falhar. Existe uma maneira padrão de conseguir a mesma coisa no Linux (CentOS em particular)?

Uma parte maior da minha pergunta é: como você lida com soquetes que foram deixados em aberto - por exemplo, nos estados TIME_WAIT, FIN_WAIT1 etc.

No momento, se o serviço que estou desenvolvendo falhar, esperarei que os soquetes limpem ou alterem a porta de escuta antes de poder reiniciá-la manualmente.

Obrigado pela ajuda.

Pryo
fonte

Respostas:

26

monité uma ótima maneira de monitorar e reiniciar serviços quando eles falham - e você provavelmente acabará usando isso para outros serviços essenciais (como o Apache). Há um bom artigo sobre o nixCraft detalhando como usá-lo especificamente para serviços, embora monitele próprio tenha muito mais funções além disso.

Quanto ao aspecto do soquete, @galraen respondeu a este ponto.

Andrew M.
fonte
É uma pena que eu tenha que decidir qual é a resposta. Eu deveria ter feito duas perguntas separadas. @gelraen sua resposta acabou de terminar minhas semanas de busca de uma solução. Agradece por isso muito! Obrigado Redmumba, Monit parece ser bom!
Pryo
Qualquer um que você decidir marcar correto, definitivamente upvote de @ gelraen resposta. Seu local correto e muito informativo.
26711 Andrew M.
19

Apenas respondendo à parte de reinicialização do serviço. Encontrei o Monit também, mas no CentOS 7 o systemd cuida de tudo isso para você. Você só precisa adicionar essas duas linhas ao arquivo .service (se elas ainda não estiverem lá):

Restart=always
RestartSec=3

Consulte https://jonarcher.info/2015/08/ensure-systemd-services-restart-on-failure/ para obter referência.

Se você deseja criar um serviço systemd personalizado, é bastante simples gravar seu próprio arquivo de serviço. Veja o exemplo abaixo, para um servidor http personalizado.

Inicie o editor com um novo arquivo de serviço:

vim /etc/systemd/system/httpd.service

E adicione o seguinte conteúdo, que você pode editar conforme necessário:

[Unit]
Description=My httpd Service
After=network.target

[Service]
Type=simple
User=root
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
Environment=PERLLIB=/perl
ExecStart=/bin/httpd /etc/httpd.conf
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target

Quero que ele inicie automaticamente na inicialização:

systemctl enable httpd

Informe o systemd sobre as alterações e inicie o serviço:

systemctl daemon-reload
systemctl start httpd

E agora você pode ver o status:

systemctl status httpd

Para referência, consulte https://scottlinux.com/2014/12/08/how-to-create-a-systemd-service-in-linux-centos-7/

Nagev
fonte
Sim, exatamente, systemdo gerente de serviços padrão das distribuições mais populares pode fazer isso por você.
Rolf
13

Você pode ligar setsockopt(2)para o soquete de escuta SO_REUSEADDR, para poder utilizá- bind(2)lo novamente sem esperar pela expiração de todas as conexões. Outra possibilidade: descartar conexões do kernel. O FreeBSD tem tcpdropcomando para isso, não conhece o Linux.

gelraen
fonte
4

Se sua distribuição Linux usa o Upstart em vez do SysV init, a respawnpalavra - chave faz isso.

http://upstart.ubuntu.com/cookbook/#respawn

JeffG
fonte
Obrigado, isso parece exatamente a coisa, mas infelizmente estou preso ao SysV init.
Pryo