
Quero iniciar um grande número (por exemplo, 256) de serviços com o systemd. Felizmente, o systemd oferece fatias que facilitam a reutilização da descrição do serviço. Mas iniciar muitos processos ao mesmo tempo mata o sistema, porque cada processo faz alguns cálculos de inicialização, o que aumenta a carga acima de 50.
É possível definir uma cadeia de dependência para todos os serviços com fatias, After=service@%(i-1).service Wants=service@%(i-1).service? Ou é possível definir algo como um pool de serviços e o systemd gerencia o início dos serviços, ou seja, não rodando todos de uma vez, mas iniciando talvez 10 de uma vez e depois disso o próximo bloco?
Responder1
Encontrei uma boa solução usando ExecStartPost
.
% systemctl --user cat example@
# /home/joerg/.config/systemd/user/[email protected]
[Unit]
Description=Example of service farm; instance %i
[Service]
Type=simple
ExecStart=/bin/sleep 99999
ExecStartPost=/bin/sh -c 'test %i -gt 0 || exit 0 ; systemctl --no-block --user start %p@$((%i - 1))'
% systemctl --user start example@2
% systemctl --user status example.slice
● example.slice
Loaded: loaded
Active: active since Thu 2017-04-27 11:04:43 CEST; 27min ago
CGroup: /user.slice/user-1000.slice/[email protected]/example.slice
├─[email protected]
│ └─19423 /bin/sleep 99999
├─[email protected]
│ └─19420 /bin/sleep 99999
└─[email protected]
└─19417 /bin/sleep 99999
Responder2
Não, o systemd não suporta uma sintaxe como Wants=service@%(i-1).service?
.
No entanto, você pode escrever um script simples que grave 256 arquivos de unidade systemd semelhantes que contenham uma cadeia de dependência explícita. Aqui estão alguns outros padrões a serem considerados:
systemd
permite definir parâmetros de controle de recursos em tempo de execução, com sintaxe como:systemctl --runtime set-property foobar.service CPUShares=777
Assim, você pode acelerar suas unidades durante a inicialização para que cada uma use menos CPU e, depois que as coisas se acalmarem, permita que elas usem mais CPU. Isso parece mais difícil do que o necessário, o que me leva à próxima opção...
- Em
man systemd.resource-control
, você descobrirá que existe umaStartupCPUShares=
opção distinta daCPUShares=
opção. Eu experimentaria limitar a CPU paraStartupCPUShares=
ver se produz o resultado desejado.
Pessoalmente, usei uma rota de tecnologia muito baixa para resolver um problema como este. Comecei minha série de serviços um de cada vez, com um “sono” entre o início dos serviços. Isso usou um pouco de script bash em vez de system
, mas funcionou bem o suficiente. Felizmente, também não tenho a necessidade de colocar todos os serviços online o mais rápido possível.
Provavelmente irei projetar a próxima iteração do sistema systemd
e tentarei usá StartupCPUShares=
-la para ver se é a melhor maneira de resolver o problema.