讓 systemd 服務稍後停止,而不會阻塞 systemctl stop
我有一堆服務負責執行隊列中消耗的操作。
我希望能夠輕輕地重新啟動服務(不中斷已經執行的操作)
可以通過處理 systemd 發送的 SIGTERM 並保存程序在目前操作處理後應該退出的資訊來解決。
還有一個小問題是,在服務配置文件中定義的一段時間後,
TimeoutStopSec
systemd 將發送額外的 SIGKILL 以殘酷地終止我的程序。我可以通過設置輕鬆避免它
TimeoutStopSec=infinity
。然後systemctl stop
‘將等到腳本自行終止,這可能會持續一個多小時,並導致我遇到主要問題。我不希望
systemctl
命令等到腳本結束看起來
SendSIGKILL=no
配置完成了這項工作。SIGTERM
這導致在之後重試TimeoutStopSec
,然後創建新的工作人員,並讓舊的工作人員繼續執行。journalctl 日誌
May 06 14:14:43 jaku systemd[1]: Stopping Jaku test worker... May 06 14:14:43 jaku python3[31597]: * 15 <frame object at 0x14d8108> May 06 14:14:53 jaku systemd[1]: jaku-test-worker.service: State 'stop-sigterm' timed out. Skipping SIGKILL. May 06 14:14:53 jaku python3[31597]: * 15 <frame object at 0x14d8108> May 06 14:15:03 jaku systemd[1]: jaku-test-worker.service: State 'stop-final-sigterm' timed out. Skipping SIGKILL. Entering failed mode. May 06 14:15:03 jaku systemd[1]: jaku-test-worker.service: Failed with result 'timeout'. May 06 14:15:03 jaku systemd[1]: Stopped Jaku test worker. May 06 14:15:03 jaku systemd[1]: jaku-test-worker.service: Found left-over process 31597 (python3) in control group while starting unit. Ignoring. May 06 14:15:03 jaku systemd[1]: This usually indicates unclean termination of a previous run, or service implementation deficiencies. May 06 14:15:03 jaku systemd[1]: Started Jaku test worker.
jaku@jaku:/nfs/home/jaku/tmp$ ps aux | grep "sig.py" jaku 31597 99.9 0.0 31884 9916 ? Rs 14:00 15:10 /usr/bin/python3 /home/jaku/tmp/sig.py jaku 32359 100 0.0 31884 10032 ? Rs 14:15 0:43 /usr/bin/python3 /home/jaku/tmp/sig.py jaku 32483 0.0 0.0 15968 1040 pts/7 S+ 14:15 0:00 grep --color=auto sig.py
解決方案看起來像是在做它的工作,但我很擔心這句話:
這通常表示先前執行的不干淨終止,或服務實現缺陷。
我錯過了什麼或者它真的是最好的解決方案嗎?
參考:
看起來沒有辦法解決它,這裡有一些 相關的執行緒。但是……我不希望**命令等到腳本結束
的假設是錯誤的。
systemctl
我希望這個命令簡短,因為它必須是 jenkins 部署的一部分,而且我不希望部署過程花費超過幾分鐘。
我不知道的是,中斷
systemctl
命令不會停止關閉服務的過程,所以可能的解決方案是:
systemctl
有時間限制的執行命令,例如timeout 60 systemctl restart services-preifx-* || echo "processes will be restart in background"
現在
TimeoutStopSec
可以設置為某個較高的值(如 10h)以防止服務永遠重啟。另外
KillMode=process
必須設置,不要中斷任何子程序。
systemd 停止服務的想法是終止與該單元的 cgroup 關聯的所有程序。執行
ExecStop=
之後再發送KillSignal=
,最後如果有必要FinalKillSignal=
。對我來說似乎很合理。您的軟體正在處理 SIGTERM,使程序保持活動狀態,然後將該單元配置為不發送 SIGKILL。systemd 認為這是損壞的,警告意味著“服務實現缺陷”。它沒有停止。
我不希望 systemctl 命令等到腳本結束
然後在一分鐘左右關閉。服務的使用者不想等待它關閉;
DefaultTimeoutStopSec=
大概是90年代。雖然您的服務單位可以增加TimeoutStopSec=
,但我認為一個小時是不合理的時間來等待初始化腳本中停止的事情。如果您有(同步)停止腳本,請將其實現為
ExecStop=
. 如果不是,請立即將 SIGTERM 處理為正常關閉。啟用 SIGKILL 作為停止它的最後手段。除了殺死它的程序之外,還有其他方法可以阻止服務開始工作。例如,將其從負載均衡器中移除並耗盡負載。