
Ich möchte eine große Anzahl (z. B. 256) von Diensten mit systemd starten. Glücklicherweise bietet systemd Slices, wodurch die Wiederverwendung der Dienstbeschreibung recht einfach ist. Wenn jedoch viele Prozesse gleichzeitig gestartet werden, wird das System zerstört, da jeder Prozess einige Startberechnungen durchführt, wodurch die Last auf über 50 steigt.
Ist es möglich, eine Abhängigkeitskette für alle Dienste mit Slices zu definieren, After=service@%(i-1).service Wants=service@%(i-1).service? Oder ist es möglich, so etwas wie einen Dienstpool zu definieren und systemd verwaltet den Start der Dienste, d. h. nicht alle auf einmal auszuführen, sondern vielleicht 10 auf einmal zu starten und danach den nächsten Block?
Antwort1
Ich habe eine gute Lösung gefunden mit 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
Antwort2
Nein, systemd unterstützt eine Syntax wie nicht Wants=service@%(i-1).service?
.
Sie könnten jedoch ein einfaches Skript schreiben, das 256 ähnliche Systemd-Unit-Dateien ausgibt, die eine explizite Abhängigkeitskette enthalten. Hier sind einige andere Muster, die Sie berücksichtigen sollten:
systemd
ermöglicht Ihnen, Ressourcensteuerungsparameter zur Laufzeit mit einer Syntax wie der folgenden festzulegen:systemctl --runtime set-property foobar.service CPUShares=777
Sie könnten also Ihre Einheiten beim Start drosseln, um jeweils weniger CPU zu verwenden, und ihnen dann, wenn sich die Lage beruhigt hat, erlauben, mehr CPU zu verwenden. Das scheint schwieriger als nötig, was mich zur nächsten Option bringt ...
- Unter
man systemd.resource-control
werden Sie feststellen, dass es eineStartupCPUShares=
Option gibt, die sich von der Option unterscheidetCPUShares=
. Ich würde mit der Drosselung der CPU experimentieren, umStartupCPUShares=
zu sehen, ob dies das gewünschte Ergebnis liefert.
Ich persönlich habe einen sehr einfachen Weg gewählt, um ein solches Problem zu lösen. Ich habe meine Reihe von Diensten einzeln gestartet, mit einer „Ruhepause“ zwischen den Dienststarts. Dafür habe ich ein wenig Bash-Skripting anstelle von verwendet system
, aber es hat gut genug funktioniert. Zum Glück habe ich auch nicht die Anforderung, alle Dienste so schnell wie möglich online zu bringen.
Die nächste Iteration des Systems werde ich wahrscheinlich darum herum entwerfen systemd
und es gerne StartupCPUShares=
selbst ausprobieren, um zu sehen, ob es eine bessere Möglichkeit zur Problemlösung darstellt.