Linux

配置有缺陷的 systemd 服務以通過 SIGKILL 終止

  • February 17, 2019

背景

我被要求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
  • 最多等待 2 秒foo_daemon以完成關機/終止。
  • 如果程序仍然存在,請嘗試強制關閉foo_daemonvia SIGKILL(因此我們沒有 PID 被回收和針對錯誤 PID 的systemd問題的風險)。SIGKILL我們正在測試的設備會快速生成/分叉許多程序,因此很少但非常真實地擔心 PID 回收會導致問題。
  • 如果在實踐中,我只是對 PID 回收有偏執,我可以接受只SIGKILL針對程序的 PID 發出的腳本,而不用擔心殺死回收的 PID。

systemd 已經開箱即用地支持此功能,並且預設情況下已啟用

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

[Service]
TimeoutStopSec=2

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

如果您的服務不支持 systemd,您可能需要使用PIDFile=.

最後,您提到您的守護程序產生了許多程序。在這種情況下,您可能希望設置KillMode=control-group並且 systemd 將向 cgroup 中的所有程序發送信號。

引用自:https://serverfault.com/questions/928376