O SystemD gera N processos?

12

Na minha organização, temos vários processos de trabalho que consomem fila. No momento, estamos usando o SupervisorD para gerenciá-los, mas gostaríamos de usar o SystemD, se possível, para determinadas vantagens. Tenho bastante experiência em escrever unidades personalizadas, mas não tenho imediatamente um analógico no SystemD para isso.

Na documentação do SupervisorD,numprocs é detalhado um parâmetro chamado que permite definir o número de processos que eles gostariam de iniciar com o serviço. Se eu quero que 30 processos sejam iniciados, é uma alteração de uma linha.

Existe uma configuração nas unidades SystemD que permita especificar quantos desses processos eu gostaria de iniciar?

Naftuli Kay
fonte
1
Você está tentando criar várias instâncias da mesma unidade? Se assim for, você pode querer olhar para 0pointer.de/blog/projects/instances.html
Munir

Respostas:

30

O que Munir mencionou é exatamente como você faz isso. Basicamente, você cria um servicearquivo e o inicia 30 vezes. Agora isso pode parecer um pouco desordeiro, mas tem vantagens, como poder desligar um deles se estiver se comportando mal e não precisar desligá-lo. Também há algumas coisas que você pode fazer para facilitar o gerenciamento.

Primeiro, o arquivo da unidade. Crie um arquivo, como /etc/systemd/system/[email protected]. O bit importante é o @símbolo.

Seu conteúdo pode se parecer com:

[Service]
ExecStart=/bin/sleep 600 %I

[Install]
WantedBy=multi-user.target

Em seguida, começar com systemctl start [email protected], systemctl start [email protected].
Os processos iniciados terão a seguinte aparência:

root     17222  19   0  0.0  0.0 Ss         00:05 /bin/sleep 600 1
root     17233  19   0  0.0  0.0 Ss         00:02 /bin/sleep 600 2

Observe que ele %Ifoi substituído pelo que você colocou depois de @quando o iniciou.

Você pode iniciar todos os 30 com um pouco de shell-fu:

systemctl start test@{1..30}.service

Você também pode ativá-los na inicialização como qualquer serviço normal: systemctl enable [email protected].

 

Agora, o que eu quis dizer com coisas que você pode fazer para facilitar o gerenciamento: talvez você não queira usar test@{1..30}.servicepara gerenciar todos eles. É um pouco pesado. Você pode criar um novo destino para o seu serviço.

Crie /etc/systemd/system/test.targetcom:

[Install]
WantedBy=multi-user.target

Em seguida, ajuste o /etc/systemd/system/[email protected]para que fique parecido com:

[Unit]
StopWhenUnneeded=true

[Service]
ExecStart=/bin/sleep 600 %I

[Install]
WantedBy=test.target

Recarregue systemd com systemctl daemon-reload(necessário apenas se você estiver modificando o arquivo da unidade e não pular a versão anterior). E agora habilite todos os serviços que você deseja que sejam gerenciados systemctl enable test@{1..30}.service.
(Se você havia ativado o serviço anteriormente WantedBy=multi-user.target, desative-o primeiro para limpar a dependência)

Agora você pode fazer systemctl start test.targete systemctl stop test.target, e ele iniciará / parará todos os 30 processos.
E, novamente, você pode habilitar a inicialização como qualquer outro arquivo unidade: systemctl enable test.target.

Patrick
fonte
Obrigado por esta resposta detalhada, pesquisei por vários dias.
Arnolem
1
Você sabe se isso reiniciará os processos que falharam?
Bastian
@bastian: você pode usar Restart=on-failure. Leia a systemd.servicepágina do manual para mais.
siride
1

Aqui está o meu exemplo usando um script python que é executado em um virtualenv:

/etc/systemd/system/[email protected]

[Unit]
Description=manages my worker service, instance %i
After=multi-user.target

[Service]
PermissionsStartOnly=true
Type=idle
User=root
ExecStart=/usr/local/virtualenvs/bin/python /path/to/my/script.py
Restart=always
TimeoutStartSec=10
RestartSec=10

Desativar: sudo systemctl enable my-worker\@{1..30}.service

Habilite N trabalhadores: sudo systemctl enable my-worker\@{1..2}.service

Recarregar: sudo systemctl daemon-reload

Começar: sudo systemctl start [email protected]

Verificar status: sudo systemctl status my-worker@1

Radtek
fonte