
我看過很多流程經理嘗試這樣做。據我了解,您應該只使用 SIGTERM 來終止進程。該進程可能需要未知的時間來自行清理;在緩慢的系統上,可能需要幾分鐘的時間。我一直認為唯一的解決辦法就是耐心等待程序清理並優雅退出。如果進程沒有捕獲 SIGTERM,則這是一個錯誤,應報告給軟體的維護人員。
我見過像 docker 這樣的流行工具也嘗試這樣做:
用法: docker stop [選項] CONTAINER [CONTAINER...]
停止正在運作的容器(發送 SIGTERM,然後在寬限期後發送 SIGKILL)
這是不好的做法嗎?我還好奇的一件事是關閉過程如何在 SystemV 風格的 init 系統上運作。我查看了一些手冊頁和其他一些問題,但找不到明確的答案。我猜測每個初始化服務(術語?)都會看到運行級別的變化並執行初始化腳本中定義的正確的“停止”函數。它是否會逐一執行此操作,確保每項服務正確結束?未由 init 腳本處理的進程會發生什麼情況?我看到一些問題模糊地提到了在 SIGKILL 之前使用的寬限期,但我希望有人能夠詳細說明或至少為我指出正確的方向。 :)
如果有人可以幫助我了解更多關於 systemd 的工作原理,我很樂意研究並了解更多。我查看了手冊頁,但也找不到任何明確的資訊。
答案1
你可以選擇吃蛋糕,也可以吃掉它。程式希望有足夠長的時間來回應 SIGTERM。系統(程式管理器)希望能夠終止。如果系統永遠等待,則允許程式透過從不回應來劫持系統關閉(因為該程式是惡意的或因為它有錯誤)。
在正常的關閉序列中,每個守護程序都透過守護程序的作者或打包者提供的 init 腳本(如果需要,可以稱為關閉腳本)終止。根據守護程式的不同,init 腳本可能只會向其發送一個訊號,也可能執行更受控制的關閉(例如,透過寫入套接字)。 init 腳本可能會等待守護程序報告它已圓滿關閉,或者可能會強行終止它。初始化腳本以 root 身分執行(它們可能會以su
權限較低的使用者身分呼叫來執行部分任務);他們應該是合作的,所以他們可以讓系統永遠掛起。
一旦初始化腳本完成其工作,所有服務都應該關閉。任何剩餘的進程都應該是不重要的或行為不當的。因此,在這個階段,剩餘的進程被告知關閉(SIGTERM),並且在寬限期(給它們最後一次徹底關閉的機會)之後,系統必須關閉,以便強行終止任何剩餘的進程(SIGKILL)。
將初始化腳本視為正常的逮捕程序 - 出示逮捕令、大聲警告等。一旦正常進程完成,剩餘的守護程式就被認為是敵對的。系統發出警告訊號 (SIGTERM),然後在延遲後發出 SIGKILL。