
Quiero iniciar una gran cantidad (por ejemplo, 256) de servicios con systemd. Afortunadamente, systemd ofrece segmentos que hacen que sea bastante fácil reutilizar la descripción del servicio. Pero iniciar muchos procesos a la vez mata el sistema, porque cada proceso realiza algún cálculo de inicio, lo que eleva la carga por encima de 50.
¿Es posible definir una cadena de dependencia para todos los servicios con sectores, After=service@%(i-1).service Wants=service@%(i-1).service? ¿O es posible definir algo así como un grupo de servicios y systemd gestiona el inicio de los servicios, es decir, no ejecutarlos todos a la vez sino iniciar tal vez 10 a la vez y luego el siguiente bloque?
Respuesta1
Encontré una buena solución 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
Respuesta2
No, systemd no admite una sintaxis como Wants=service@%(i-1).service?
.
Sin embargo, podría escribir un script simple que escriba 256 archivos de unidades systemd similares que contengan una cadena de dependencia explícita. Aquí hay algunos otros patrones a considerar:
systemd
le permite configurar parámetros de control de recursos en tiempo de ejecución, con una sintaxis como:systemctl --runtime set-property foobar.service CPUShares=777
Por lo tanto, puede acelerar sus unidades durante el inicio para que cada una use menos CPU y luego, una vez que las cosas se hayan calmado, permitirles usar más CPU. Esto parece más difícil de lo necesario, lo que me lleva a la siguiente opción...
- En
man systemd.resource-control
, encontrará que hay unaStartupCPUShares=
opción que es distinta de laCPUShares=
opción. Experimentaría acelerando la CPU paraStartupCPUShares=
ver si produce el resultado que desea.
Personalmente, utilicé una ruta de muy baja tecnología para resolver un problema como este. Comencé mi serie de servicios uno a la vez, con un "suspensión" entre el inicio del servicio. Esto usó un pequeño script bash en lugar de system
, pero funcionó bastante bien. Afortunadamente, tampoco tengo el requisito de poner todos los servicios en línea lo antes posible.
Probablemente diseñaré la próxima versión del sistema systemd
y me gustaría intentar usarla StartupCPUShares=
yo mismo para ver si es una mejor manera de resolver el problema.