Latar Belakang
Saya diminta untuk membuat systemd
skrip untuk layanan baru foo_daemon
,, yang terkadang masuk ke "kondisi buruk", dan tidak akan mati melalui SIGTERM
(kemungkinan karena penangan sinyal khusus). Ini bermasalah bagi pengembang, karena mereka diperintahkan untuk memulai / menghentikan / memulai kembali layanan melalui:
systemctl start foo_daemon.service
systemctl stop foo_daemon.service
systemctl restart foo_daemon.service
Masalah
Terkadang, karena foo_daemon
masuk ke kondisi buruk, kita harus membunuhnya secara paksa melalui:
systemctl kill -s KILL foo_daemon.service
Pertanyaan
Bagaimana saya dapat mengatur systemd
skrip saya foo_daemon
sehingga, setiap kali pengguna mencoba menghentikan / memulai kembali layanan, systemd
akan:
- Mencoba shutdown
foo_daemon
viaSIGTERM
. - Berikan hingga 2 detik untuk shutdown / terminasi
foo_daemon
hingga selesai. - Coba shutdown paksa
foo_daemon
melaluiSIGKILL
jika proses masih hidup (jadi kami tidak memiliki risiko PID didaur ulang dansystemd
masalahSIGKILL
terhadap PID yang salah). Perangkat yang kami uji memunculkan / memalsukan banyak proses dengan cepat, sehingga ada kekhawatiran yang jarang namun sangat nyata tentang daur ulang PID yang menyebabkan masalah. - Jika, dalam praktiknya, saya hanya menjadi paranoid tentang daur ulang PID, saya setuju dengan skrip yang hanya
SIGKILL
menentang proses PID tanpa khawatir akan membunuh PID daur ulang.
Jawaban:
systemd sudah mendukung ini di luar kotak, dan itu diaktifkan secara default .
Satu-satunya hal yang Anda ingin sesuaikan adalah batas waktu, yang dapat Anda lakukan dengan
TimeoutStopSec=
. Sebagai contoh:Sekarang, systemd akan mengirim SIGTERM, menunggu dua detik hingga layanan keluar, dan jika tidak, ia akan mengirim SIGKILL.
Jika layanan Anda tidak sadar sistem, Anda mungkin perlu menyediakan path ke file PID-nya
PIDFile=
.Akhirnya, Anda menyebutkan bahwa daemon Anda memunculkan banyak proses. Dalam hal ini, Anda mungkin ingin mengatur
KillMode=control-group
dan systemd akan mengirim sinyal ke semua proses di cgroup.sumber
Type=simple
dalam unit systemd.Type=forking
memiliki keunggulan (jika layanan ditulis dengan benar) memberi tahu systemd ketika sepenuhnya 'siap' yang Tipe = sederhana tidak dapat lakukan. Daemonisasi bukanlah masalah, bahkan tanpa file PID - systemd akan melacak proses utamanya.Type=notify
terbaik untuk systemd, dan banyak layanan umum sudah melakukan ini. Tapi mungkin bukan layanan warisan ini. Dalam kasus OP, ia memiliki layanan yang memunculkan banyak proses. Systemd docs memperingatkan tentang kasus ini .Karena tidak ada yang menyebutkan perlu
Type=oneshot
, berikut adalah contoh lengkap yang keluar karena kegagalan waktu habis.sumber