Czy SystemD spawnuje N procesów?

13

W mojej organizacji mamy wiele kolejek zajmujących procesy robocze. Obecnie używamy SupervisorD do zarządzania nimi, ale chcielibyśmy użyć SystemD, jeśli to możliwe, aby uzyskać pewne korzyści. Mam dość doświadczenie w pisaniu niestandardowych jednostek, ale nie mam od razu analogu w ziemi SystemD.

W dokumentacji SupervisorD nazwany parametr numprocsjest szczegółowy, co pozwala ustawić liczbę procesów, które chcieliby zostać uruchomione z usługą. Jeśli chcę, aby uruchomiono 30 procesów, jest to zmiana jednowierszowa.

Czy w jednostkach SystemD jest ustawienie, które pozwoli mi określić, ile z tych procesów chciałbym rozpocząć?

Naftuli Kay
źródło
1
Czy próbujesz utworzyć wiele wystąpień tej samej jednostki? Jeśli tak, możesz spojrzeć na 0pointer.de/blog/projects/instances.html
Munir

Odpowiedzi:

31

Munir wspomniał dokładnie, jak to robisz. Zasadniczo tworzysz serviceplik i uruchamiasz go 30 razy. Teraz może to wydawać się trochę niewygodne, ale ma zalety, takie jak możliwość zamknięcia jednego z nich, jeśli jest źle funkcjonujący, i nie trzeba wyłączać wszystkich. Istnieje również kilka rzeczy, które możesz zrobić, aby ułatwić zarządzanie.

Najpierw plik jednostki. Utwórz plik, taki jak /etc/systemd/system/[email protected]. Ważnym elementem jest @symbol.

Jego zawartość może wyglądać następująco:

[Service]
ExecStart=/bin/sleep 600 %I

[Install]
WantedBy=multi-user.target

Następnie należy uruchomić go systemctl start [email protected], systemctl start [email protected].
Uruchomione procesy będą wyglądały następująco:

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

Zauważ, że %Izostał zastąpiony czymkolwiek, co umieścisz po jego @uruchomieniu.

Możesz zacząć wszystkie 30 od małego shell-fu:

systemctl start test@{1..30}.service

Można także włączyć je w bagażniku jak każdy normalny usługi: systemctl enable [email protected].

 

Co mam na myśli, mówiąc o rzeczach, które możesz zrobić, aby ułatwić zarządzanie: Być może nie chcesz używać wszystkich test@{1..30}.servicedo zarządzania nimi. To jest trochę nieporęczne. Zamiast tego możesz utworzyć nowy cel dla swojej usługi.

Utwórz za /etc/systemd/system/test.targetpomocą:

[Install]
WantedBy=multi-user.target

Następnie dostosuj /etc/systemd/system/[email protected]tak, aby wyglądało tak:

[Unit]
StopWhenUnneeded=true

[Service]
ExecStart=/bin/sleep 600 %I

[Install]
WantedBy=test.target

Załaduj ponownie systemd za pomocą systemctl daemon-reload(konieczne tylko, jeśli modyfikujesz plik jednostki i nie pomijałeś jego wcześniejszej wersji). A teraz włącz wszystkie usługi, którymi chcesz zarządzać systemctl enable test@{1..30}.service.
(Jeśli wcześniej włączyłeś tę usługę WantedBy=multi-user.target, wyłącz ją najpierw, aby usunąć zależność)

Możesz teraz zrobić systemctl start test.targeti systemctl stop test.target, a to uruchomi / zatrzyma wszystkie 30 procesów.
I znów, można włączyć przy starcie jak każdy inny plik jednostki: systemctl enable test.target.

Patrick
źródło
Dziękuję za tę szczegółową odpowiedź, szukałem tego przez kilka dni.
arnolem
1
Czy wiesz, czy to uruchomi ponownie procesy, które się nie powiodły?
bastian
@ Bastian: możesz użyć Restart=on-failure. Przeczytaj systemd.servicestronę podręcznika, aby uzyskać więcej.
Sir
1

Oto mój przykład przy użyciu skryptu python działającego w virtualenv:

/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

Wyłączyć: sudo systemctl enable my-worker\@{1..30}.service

Włącz N pracowników: sudo systemctl enable my-worker\@{1..2}.service

Przeładować: sudo systemctl daemon-reload

Początek: sudo systemctl start [email protected]

Sprawdź status: sudo systemctl status my-worker@1

radtek
źródło