tło
Poproszono mnie o stworzenie systemd
skryptu dla nowej usługi, foo_daemon
która czasami przechodzi w „zły stan” i nie umrze przez SIGTERM
(prawdopodobnie z powodu niestandardowej procedury obsługi sygnałów). Jest to problematyczne dla programistów, ponieważ są oni instruowani, aby uruchomić / zatrzymać / zrestartować usługę poprzez:
systemctl start foo_daemon.service
systemctl stop foo_daemon.service
systemctl restart foo_daemon.service
Problem
Czasami, z powodu foo_daemon
popadnięcia w zły stan, musimy siłą go zabić poprzez:
systemctl kill -s KILL foo_daemon.service
Pytanie
Jak skonfigurować systemd
skrypt, foo_daemon
aby za każdym razem, gdy użytkownik spróbuje zatrzymać / ponownie uruchomić usługę, systemd
będzie:
- Spróbuj z wdziękiem wyłączyć
foo_daemon
viaSIGTERM
. - Daj do 2 sekund na zakończenie / zakończenie działania
foo_daemon
. - Próbować wymuszone wyłączenie
foo_daemon
poprzezSIGKILL
jeśli proces jest wciąż żywy (więc nie ma ryzyka PID zawraca isystemd
problemySIGKILL
przed niewłaściwym PID). Testowane przez nas urządzenie odradza się / rozwidla szybko wiele procesów, więc istnieje rzadka, ale bardzo realna obawa o to, że recykling PID powoduje problem. - Jeśli w praktyce jestem po prostu paranoikiem odnośnie recyklingu PID, nie mam nic
SIGKILL
przeciwko skryptowi, który wystawia się przeciwko procesowi PID, nie martwiąc się o zabicie przetworzonego PID.
Odpowiedzi:
systemd już to obsługuje i jest domyślnie włączony .
Jedyne, co możesz chcieć dostosować, to limit czasu, który możesz zrobić
TimeoutStopSec=
. Na przykład:Teraz systemd wyśle SIGTERM, poczeka dwie sekundy na zakończenie usługi, a jeśli nie, wyśle SIGKILL.
Jeśli Twoja usługa nie obsługuje systemu, może być konieczne podanie ścieżki do pliku PID
PIDFile=
.Na koniec wspomniałeś, że twój demon spawnuje wiele procesów. W takim przypadku możesz chcieć ustawić,
KillMode=control-group
a systemd wyśle sygnały do wszystkich procesów w grupie.źródło
Type=simple
w jednostce systemd.Type=forking
ma tę zaletę, że (jeśli usługa została poprawnie napisana) informuje systemd, kiedy jest w pełni „gotowa”, czego Type = simple nie może zrobić. Demonizacja nie stanowi problemu, nawet bez pliku PID - systemd i tak wyśledzi główny proces.Type=notify
jest najlepsza dla systemd, a wiele popularnych usług już to robi. Ale prawdopodobnie nie ta starsza usługa. W przypadku PO ma on usługę, która odradza wiele procesów. Systematyczni doktorzy ostrzegają o tej sprawie .Ponieważ nikt nie wspomniał o potrzebie
Type=oneshot
, oto kompletny przykład, który kończy się z powodu awarii limitu czasu.źródło