Server Rumahan & Self-Hosting

Service Watchdog systemd - Mendeteksi Proses yang Hidup tetapi Tidak Lagi Bergerak Maju

Service Watchdog systemd - Mendeteksi Proses yang Hidup tetapi Tidak Lagi Bergerak Maju

Sebuah proses masih bisa memiliki PID, memakai sedikit CPU, dan terlihat sebagai active (running) meski pekerjaan bergunanya sudah berhenti. Event loop-nya mungkin terblokir, worker mungkin menunggu tanpa akhir, atau satu lock internal mungkin menghalangi semua request untuk bergerak maju. Aturan restart yang hanya bergantung pada proses keluar tidak dapat bereaksi karena proses tersebut belum keluar.

Service watchdog systemd menawarkan sinyal yang lebih sempit: aplikasi yang mendukungnya berjanji mengirim pesan keep-alive secara berkala. Jika pesan itu berhenti, systemd menganggap tenggat yang terlewat sebagai kegagalan. Kata yang penting adalah mendukung. Menambahkan satu directive tidak mengajari daemon sembarang cara melaporkan kesehatan, dan heartbeat bukan bukti bahwa pengguna menerima respons yang benar.

Jadi, pertanyaan yang berguna bukan sekadar, "Bagaimana cara mengaktifkan WatchdogSec=?" Pertanyaannya adalah: progress apa yang diwakili setiap heartbeat, dan apa yang seharusnya terjadi ketika bukti itu menghilang?

Berjalan, responsif, dan benar adalah keadaan yang berbeda

Supervisi proses dapat menjawab apakah sebuah proses dimulai, keluar, menerima signal, atau melewati timeout yang dikonfigurasi. Itu sudah menangkap banyak kegagalan. Namun, mekanisme tersebut tidak otomatis mengetahui apakah main loop masih bergerak atau apakah aplikasi menghasilkan keluaran yang benar.

Service watchdog menambahkan sinyal dari aplikasi ke manager. Menurut manual Debian berversi systemd.service(5), WatchdogSec= mengatur tenggat setelah startup selesai. Layanan harus memberi tahu systemd secara berkala dengan WATCHDOG=1. Jika jarak waktu antar-notifikasi terlalu panjang, systemd menandai unit sebagai gagal dan menghentikannya dengan SIGABRT secara default; WatchdogSignal= dapat memilih signal lain.

Ini lebih kuat daripada "PID-nya ada", tetapi lebih lemah daripada pemeriksaan end-to-end. Program dapat mengirim heartbeat sambil mengembalikan respons HTTP 500, membaca data lama, atau gagal menjangkau database. Watchdog hanya mengetahui bahwa jalur kode yang bertanggung jawab atas pesannya sempat berjalan sebelum tenggat.

Watchdog adalah kontrak dua arah

Unit file menyediakan tenggat. systemd kemudian menyampaikan tenggat itu kepada layanan melalui WATCHDOG_USEC, dalam mikrodetik, dan dapat menyediakan WATCHDOG_PID untuk mengidentifikasi proses yang diharapkan. API sd_watchdog_enabled(3) memungkinkan daemon memeriksa nilai-nilai tersebut, alih-alih menanam interval secara hard-coded.

Pada arah sebaliknya, aplikasi mengirim notifikasi melalui socket yang ditunjuk oleh NOTIFY_SOCKET. Dokumentasi protokol sd_notify(3) mendefinisikan WATCHDOG=1 sebagai pesan keep-alive yang memperbarui timestamp watchdog systemd. Dokumentasi itu juga mendefinisikan READY=1, yang melaporkan selesainya startup untuk layanan Type=notify. Readiness adalah sebuah transisi; heartbeat watchdog adalah bukti yang berulang.

Dokumentasi upstream menyarankan pengiriman keep-alive setiap setengah interval watchdog. Untuk tenggat 30 detik, ini berarti menargetkan sekitar setiap 15 detik, bukan menunggu saat terakhir. Margin ini membantu menghadapi keterlambatan scheduling biasa, tetapi tidak membuat 30 detik cocok untuk semua keadaan. Tenggat harus memberi ruang bagi operasi sehat terlama pada jalur aplikasi tertentu.

Penempatan heartbeat menentukan apa yang diawasi

Bayangkan dua rancangan. Pada rancangan pertama, thread timer terpisah mengirim WATCHDOG=1 tanpa memedulikan apa yang sedang dikerjakan worker. Proses dapat terus terlihat hidup meski request loop-nya terblokir permanen. Pada rancangan kedua, main loop baru mengirim heartbeat setelah menyelesaikan iterasi yang bermakna atau memastikan worker-nya telah bergerak maju.

Rancangan kedua memberikan bukti yang lebih berguna, tetapi arti "bermakna" bergantung pada aplikasinya. Queue worker mungkin perlu memastikan consumer loop berhasil melakukan polling. Web server mungkin memeriksa bahwa event loop-nya terus berputar dan koordinasi worker tetap responsif. Heartbeat tidak seharusnya menjalankan diagnosis penuh yang mahal pada setiap interval, tetapi juga tidak boleh terlepas dari seluruh pekerjaan berguna.

Ini adalah interpretasi desain berdasarkan semantik protokol notifikasi, bukan jaminan yang disediakan systemd. PID 1 tidak dapat memeriksa maksud aplikasi. Pembuat daemon harus memilih progress internal mana yang mengizinkan ping dikirim.

Atribusi notifikasi juga penting. NotifyAccess= mengontrol proses layanan mana yang pesannya dapat diterima. Saat WatchdogSec= digunakan tanpa nilai eksplisit, systemd secara implisit memakai NotifyAccess=main. Dokumentasi protokol memperingatkan bahwa helper process berumur pendek bisa sulit diatribusikan kecuali akses dan sinkronisasinya dirancang dengan benar. Lebih penting lagi, helper eksternal generik yang terus melakukan ping ketika aplikasi sebenarnya macet akan menggagalkan tujuan watchdog.

Bentuk unit yang konservatif

Untuk software yang secara eksplisit mendukung notifikasi readiness dan watchdog systemd, bagian unit yang relevan mungkin terlihat seperti ini:

[Service]
Type=notify
ExecStart=/usr/local/bin/example-worker
WatchdogSec=30s
Restart=on-failure
RestartSec=10s

example-worker adalah placeholder, bukan layanan yang diamati di server ini. Konfigurasi ini hanya sesuai jika executable mengirim READY=1 setelah inisialisasi, lalu mengirim pesan WATCHDOG=1 yang dapat diatribusikan. Tanpa READY=1, layanan Type=notify tidak menyelesaikan transisi startup normalnya. Tanpa pesan watchdog yang berulang, layanan akan gagal setelah tenggat yang dikonfigurasi.

Restart=on-failure mencakup kegagalan watchdog. Restart=on-watchdog lebih sempit jika hanya watchdog yang terlewat yang seharusnya memicu restart otomatis. Keduanya tidak otomatis aman. Restart dapat mengganggu request, mengulang pekerjaan non-idempotent, atau menambah beban pada dependency yang tidak sehat. Percobaan otomatis juga tunduk pada start-rate limit systemd.

Kebijakan restart yang ada, perilaku shutdown, persistent state, dan kontrak recovery tetap perlu ditinjau. Watchdog mendeteksi satu kelas kegagalan; ia tidak memutuskan apakah menjalankan ulang proses aman dilakukan.

Periksa dukungan sebelum mengubah unit

Mulailah dari dokumentasi aplikasi dan unit bawaan paketnya. Cari dukungan eksplisit untuk sd_notify, WatchdogSec, WATCHDOG_USEC, atau opsi notifikasi systemd yang terdokumentasi. Panduan integrasi systemd daemon(7) memperlakukan notifikasi status sebagai perilaku yang diimplementasikan daemon modern, bukan sesuatu yang disimpulkan manager dari keberadaan PID.

systemctl cat example-worker.service
systemctl show example-worker.service \
  --property=Type,NotifyAccess,WatchdogUSec,WatchdogTimestamp,Result

systemctl cat menampilkan unit bawaan paket dan drop-in yang dimuat dari disk. systemctl show menampilkan properti manager yang sudah dinormalisasi; setting unit file yang berakhiran Sec sering muncul sebagai properti berakhiran USec. Interval watchdog nol berarti supervisi service watchdog dinonaktifkan.

Jika layanan berbasis shell sengaja mengimplementasikan protokol ini, systemd-notify(1) adalah wrapper command-line untuk sd_notify(). Pesan watchdog adalah assignment biasa:

systemd-notify WATCHDOG=1

Command itu bukan saran untuk menambahkan cron job atau loop eksternal. Ia harus berjalan di dalam konteks layanan yang diawasi, dengan akses notifikasi yang benar, pada titik yang mewakili progress aplikasi yang nyata.

Validasi konfigurasi, lalu uji perilakunya dengan aman

Sebuah unit dapat diperiksa sebelum dipasang:

systemd-analyze verify ./example-worker.service

Manual systemd-analyze(1) menjelaskan bahwa verify dapat melaporkan masalah seperti directive yang tidak dikenal, dependency wajib yang hilang, dan command yang tidak tersedia. Hasil bersih memvalidasi sebagian konfigurasi. Hasil itu tidak dapat membuktikan bahwa aplikasi mengirim ping, bahwa ping mengikuti pekerjaan bermakna, atau bahwa restart mempertahankan data.

Pengujian perilaku sebaiknya memakai instance non-production atau maintenance window. Amati startup normal terlebih dahulu, termasuk readiness dan beberapa interval heartbeat. Lalu gunakan mekanisme pengujian yang didukung aplikasi untuk menjeda atau memblokir loop yang dipantau tanpa merusak state. Bukti yang diharapkan mencakup kegagalan watchdog di journal, termination signal yang dikonfigurasi, Result unit, dan restart yang diizinkan kebijakannya.

systemctl status example-worker.service
journalctl --unit=example-worker.service --since today
systemctl show example-worker.service \
  --property=ActiveState,SubState,Result,NRestarts,WatchdogTimestamp

Jangan menguji dengan membekukan database production, layanan storage, atau queue worker yang belum dipahami. Kegagalan paksa dapat menahan lock, memutus write, memicu retry dari client, atau menghasilkan core dump. Rencana pengujian memerlukan kondisi berhenti yang eksplisit dan rollback yang menghapus drop-in atau mengembalikan setting unit sebelumnya.

Hal yang tidak dapat dibuktikan service watchdog

  • Ia tidak dapat membuktikan bahwa respons HTTP benar atau bahkan berhasil.
  • Ia tidak dapat membuktikan bahwa database, DNS resolver, remote API, atau perangkat storage sehat.
  • Ia tidak dapat mendeteksi bug logika jika jalur heartbeat tetap berjalan.
  • Ia tidak dapat menjamin bahwa menghentikan dan menjalankan ulang proses aman.
  • Ia tidak dapat menggantikan monitoring dari sisi jaringan atau pengguna.

External health check dan internal watchdog menjawab pertanyaan yang berbeda. Pemeriksaan eksternal menanyakan apakah client dapat memperoleh hasil yang dapat diterima. Watchdog menanyakan apakah kode tertentu di dalam layanan telah melaporkan progress sebelum tenggatnya. Salah satunya bisa gagal ketika yang lain lolos. Menggunakan keduanya dapat mempersempit ketidakpastian, tetapi keduanya tidak seharusnya disebut sebagai bukti kesehatan yang lengkap.

Ada pula layanan yang hanya mendapat sedikit manfaat dari watchdog. Job berumur pendek yang sudah dibatasi runtime timeout, aplikasi tanpa titik progress yang dapat dipercaya, atau software yang tidak dapat direstart dengan aman mungkin lebih cocok mengandalkan log, alert, dan respons operator yang disengaja. Recovery yang lebih otomatis tidak selalu berarti lebih andal.

Checklist adopsi yang hati-hati

  1. Pastikan aplikasi dan versi yang tepat mendukung notifikasi watchdog systemd.
  2. Tentukan progress berguna apa yang harus terjadi sebelum heartbeat dikirim.
  3. Pilih tenggat yang lebih panjang daripada pekerjaan valid terburuk, dengan margin scheduling.
  4. Tinjau NotifyAccess= dan pastikan proses yang diharapkan mengirim pesan.
  5. Putuskan apakah kegagalan watchdog harus me-restart layanan dan apakah restart itu aman.
  6. Pertahankan start-rate limit, log, dan jalur alert agar kegagalan berulang tidak menjadi churn yang diam-diam.
  7. Verifikasi sintaks unit dan uji heartbeat yang terlewat jauh dari traffic production.
  8. Pertahankan pemeriksaan eksternal untuk perilaku yang tidak dapat diamati heartbeat internal.

Heartbeat harus memiliki arti

Service watchdog systemd mengisi celah nyata antara "proses telah keluar" dan "proses masih ada". Nilainya berasal dari kontrak kecil yang eksplisit: manager menetapkan tenggat, lalu aplikasi melaporkan progress berkelanjutan sebelum tenggat itu habis.

Mekanisme ini menjadi menyesatkan ketika ping diperlakukan sebagai ritual. Jika helper yang tidak terkait dapat mengirimkannya selamanya, sinyal hijau bertahan lebih lama daripada pekerjaan yang seharusnya diwakili. Mulailah dari model kegagalan aplikasi, tempatkan heartbeat setelah progress yang bermakna, dan perlakukan restart sebagai upaya recovery, bukan perbaikan. Hasilnya bukan pengetahuan sempurna tentang kesehatan layanan, tetapi bukti yang lebih jujur daripada PID saja.

References