Inicie um grande número de serviços com systemd

Inicie um grande número de serviços com systemd

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:

  1. systemdpermite 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...

  1. Em man systemd.resource-control, você descobrirá que existe uma StartupCPUShares=opção distinta da CPUShares=opção. Eu experimentaria limitar a CPU para StartupCPUShares=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 systemde tentarei usá StartupCPUShares=-la para ver se é a melhor maneira de resolver o problema.

informação relacionada