Linux
配置有缺陷的 systemd 服務以通過 SIGKILL 終止
背景
我被要求
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_daemon
viaSIGTERM
。- 最多等待 2 秒
foo_daemon
以完成關機/終止。- 如果程序仍然存在,請嘗試強制關閉
foo_daemon
viaSIGKILL
(因此我們沒有 PID 被回收和針對錯誤 PID 的systemd
問題的風險)。SIGKILL
我們正在測試的設備會快速生成/分叉許多程序,因此很少但非常真實地擔心 PID 回收會導致問題。- 如果在實踐中,我只是對 PID 回收有偏執,我可以接受只
SIGKILL
針對程序的 PID 發出的腳本,而不用擔心殺死回收的 PID。
systemd 已經開箱即用地支持此功能,並且預設情況下已啟用。
您可能想要自定義的唯一一件事是超時,您可以使用
TimeoutStopSec=
. 例如:[Service] TimeoutStopSec=2
現在,systemd 將發送一個 SIGTERM,等待兩秒鐘讓服務退出,如果沒有,它將發送一個 SIGKILL。
如果您的服務不支持 systemd,您可能需要使用
PIDFile=
.最後,您提到您的守護程序產生了許多程序。在這種情況下,您可能希望設置
KillMode=control-group
並且 systemd 將向 cgroup 中的所有程序發送信號。