In meiner Organisation haben wir eine Reihe von Warteschlangen verbrauchenden Arbeitsprozessen. Wir verwenden derzeit SupervisorD, um sie zu verwalten, würden aber, wenn möglich, SystemD verwenden, da dies gewisse Vorteile bietet. Ich habe ziemlich viel Erfahrung mit dem Schreiben benutzerdefinierter Einheiten, aber ich habe dafür nicht sofort ein Analogon im SystemD-Bereich.
ImSupervisorD-DokumentationEin Parameter namens „ numprocs
ist detailliert“, mit dem man die Anzahl der Prozesse festlegen kann, die mit dem Dienst gestartet werden sollen. Wenn ich 30 Prozesse starten möchte, muss ich nur eine Zeile ändern.
Gibt es in den SystemD-Einheiten eine Einstellung, mit der ich angeben kann, wie viele dieser Prozesse ich starten möchte?
Antwort1
Munir hat genau beschrieben, wie Sie das machen. Im Grunde erstellen Sie eine service
Datei und starten sie 30 Mal. Das mag ein wenig umständlich erscheinen, hat aber Vorteile, wie zum Beispiel, dass Sie eine Datei schließen können, wenn sie nicht richtig funktioniert, und nicht alle schließen müssen. Es gibt auch einige Dinge, die Sie tun können, um die Verwaltung zu vereinfachen.
Zuerst die Unit-Datei. Erstellen Sie eine Datei wie . Wichtig ist das Symbol./etc/systemd/system/[email protected]
@
Der Inhalt könnte wie folgt aussehen:
[Service]
ExecStart=/bin/sleep 600 %I
[Install]
WantedBy=multi-user.target
Starten Sie es dann mit , . Die gestarteten Prozesse sehen folgendermaßen aus:systemctl start [email protected]
systemctl start [email protected]
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
Beachten Sie, dass es %I
durch das ersetzt wurde, was Sie @
beim Starten nach dem eingegeben haben.
Sie können alle 30 mit ein wenig Shell-Fu starten:
systemctl start test@{1..30}.service
Sie können sie auch wie jeden normalen Dienst beim Booten aktivieren: .systemctl enable [email protected]
Was ich mit Dingen meinte, die Sie tun können, um die Verwaltung zu vereinfachen: Vielleicht möchten Sie nicht alle verwalten müssen test@{1..30}.service
. Das ist etwas umständlich. Sie können stattdessen ein neues Ziel für Ihren Dienst erstellen.
Erstellen /etc/systemd/system/test.target
mit:
[Install]
WantedBy=multi-user.target
Passen Sie es dann so an, dass es wie folgt aussieht:/etc/systemd/system/[email protected]
[Unit]
StopWhenUnneeded=true
[Service]
ExecStart=/bin/sleep 600 %I
[Install]
WantedBy=test.target
Laden Sie systemd mit neu systemctl daemon-reload
(nur notwendig, wenn Sie die Unit-Datei ändern und die frühere Version davon nicht übersprungen haben). Aktivieren Sie nun alle Dienste, die verwaltet werden sollen, indem Sie Folgendes tun systemctl enable test@{1..30}.service
:
(Wenn Sie den Dienst zuvor aktiviert hatten, während er aktiviert war WantedBy=multi-user.target
, deaktivieren Sie ihn zuerst, um die Abhängigkeit zu beseitigen.)
Sie können jetzt systemctl start test.target
und ausführen systemctl stop test.target
, und es werden alle 30 Prozesse gestartet/gestoppt.
Und wieder können Sie beim Booten wie jede andere Unit-Datei aktivieren: systemctl enable test.target
.
Antwort2
Hier ist mein Beispiel mit einem Python-Skript, das in einer virtuellen Umgebung ausgeführt wird:
/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
Deaktivieren:sudo systemctl disable my-worker\@{1..30}.service
N Arbeiter aktivieren:sudo systemctl enable my-worker\@{1..2}.service
Neu laden:sudo systemctl daemon-reload
Start:sudo systemctl start [email protected]
Status überprüfen:sudo systemctl status my-worker@1