背景

背景

背景

我被要求systemd為新服務建立一個腳本,foo_daemon有時會進入“不良狀態”,並且不會通過SIGTERM(可能是由於自訂訊號處理程序)而死掉。這對開發人員來說是個問題,因為他們被指示透過以下方式啟動/停止/重新啟動服務:

  • systemctl start foo_daemon.service
  • systemctl stop foo_daemon.service
  • systemctl restart foo_daemon.service

問題

有時,由於foo_daemon進入了糟糕的狀態,我們不得不透過以下方式強行殺死它:

  • systemctl kill -s KILL foo_daemon.service

問題

如何設定我的systemd腳本foo_daemon,以便每當使用者嘗試停止/重新啟動服務時,systemd將:

  • 嘗試正常關閉foo_daemonvia SIGTERM
  • foo_daemon最多需要 2 秒的時間來完成關閉/終止。
  • 如果進程仍然存在,請嘗試強制關閉foo_daemonvia SIGKILL(這樣我們就不會有 PID 被回收的風險以及針對錯誤 PID 的systemd問題)。SIGKILL我們正在測試的設備快速產生/分叉大量進程,因此,很少有人擔心 PID 回收會導致問題。
  • 在實踐中,如果我只是對 PID 回收抱持偏執,那麼我可以接受只針對進程 PID 發出的腳本,SIGKILL而不用擔心殺死回收的 PID。

答案1

systemd 已經開箱即用地支援這一點,而且它是預設啟用

您可能想要自訂的唯一事情是超時,您可以使用TimeoutStopSec=.例如:

[Service]
TimeoutStopSec=2

現在,systemd 將發送一個 SIGTERM,等待兩秒鐘讓服務退出,如果沒有退出,它將發送一個 SIGKILL。

如果您的服務不支援 systemd,您可能需要提供其 PID 檔案的路徑PIDFile=

最後,您提到您的守護程式會產生許多進程。在這種情況下,您可能想要進行設置KillMode=control-group,systemd 將向 cgroup 中的所有進程發送訊號。

答案2

由於沒有人提到需要Type=oneshot,這裡有一個完整的範例,該範例因超時失敗而退出。

[Unit]
Description=timeout test

[Service]
Type=oneshot
TimeoutStartSec=2
ExecStart=/bin/sleep 10

相關內容