DAEMON(7) | daemon | DAEMON(7) |
NAME¶
daemon - 編寫與打包系統守護進程描述¶
"守護進程"的意思是在後臺運行的服務進程, 常用於監督系統的運行或者提供某種功能。 在傳統的 SysV Unix 系統上, 多個守護進程必須嚴格按照特定的順序依次啓動。 在"新型"的 systemd(1) 系統上, 守護進程的啓動順序非常簡單且非常強大。 本手冊同時解說了上述兩種不同的啓動方案, 並特別推薦了應該包含在 systemd 系統中的守護進程。傳統的SysV守護進程¶
傳統的SysV守護進程在啓動的時候, 應該在初始化階段執行下面的步驟:注意,這些步驟對於下文講述的新型守護進程是不需要的, 除非爲了刻意兼容傳統的SysV系統。
新型守護進程¶
Linux 系統上的新型守護進程更容易被監控也更容易實現。守護進程無需實現前文所描述的複雜步驟, 即可直接在 systemd 提供的乾淨的上下文環境中運行:
環境變量已經被清理、信號處理器與信號掩碼已經被重置、沒有遺留的文件描述符、守護進程自動在其專屬的會話中執行、 標準輸入(STDIN)已被連接到 /dev/null 虛擬設備(除非另有配置)、 標準輸出(STDOUT)與標準錯誤(STDERR)已被連接到 systemd-journald.service(8) 日誌服務(除非另有配置)、umask 已經被重置 ... 等等
新型守護進程只需要遵守如下要求:
上述要求與 Apple MacOS X Daemon Requirements[2] 類似, 但並不完全相同。
啓動¶
systemd 提供了多種啓動機制(見下文), 而服務單元也經常同時使用其中的幾種。 例如 bluetoothd.service 可以在插入藍牙硬件時被啓動, 也可以在某進程訪問其 D-Bus 接口時被啓動。 又如打印服務可以在IPP端口有流量接入時被啓動, 也可以在插入打印機硬件時被啓動, 還可以在有文件進入打印機 spool 目錄時被啓動。 甚至對於必須在系統啓動時無條件啓動的服務, 爲了儘可能併發啓動, 也應該使用某些啓動機制。 如果某守護進程實現了一個 D-Bus 服務或者監聽一個套接字, 那麼使用基於 D-Bus 或基於套接字的啓動機制, 將允許該進程與其客戶端同時並行啓動(從而加快啓動速度)。 因爲所有的通信渠道都已事先建立, 並且不會丟失任何客戶端請求, 同時 D-Bus 總線或者內核會將客戶端請求排入隊列等候, 直到完成啓動。系統啓動時啓動¶
傳統的守護進程一般是在系統啓動時通過SysV初始化腳本自動啓動, systemd 也支持這種啓動方式。對於 systemd 來說, 如果希望確保某單元在系統啓動時自動啓動, 那麼最佳的做法是在默認啓動目標 (通常是 multi-user.target 或 graphical.target)的 .wants/ 目錄中爲該單元建立軟鏈接。 參見 systemd.unit(5) 手冊以瞭解 .wants/ 目錄, 參見 systemd.special(7) 手冊以瞭解上述兩個特殊的啓動目標。
基於套接字的啓動¶
爲了儘可能提高並行性與健壯性, 以及簡化配置與開發, 對於需要監聽套接字的服務, 強烈推薦使用基於套接字的啓動機制。 使用此機制後, 守護進程不再需要創建和綁定套接字, 而是由 systemd 接管這個工作。 systemd 將會根據單元文件的設置, 預先創建所需的套接字, 並在第一個客戶端請求接入的時候啓動該服務, 以實現服務的按需啓動。 該機制的好處還在於, 預先創建好套接字之後, 所有使用此套接字通信的進程可以並行啓動(包括客戶端和服務端)。 此外,重啓服務只會導致丟失最低限度的客戶端連接, 甚至不丟失任何客戶端請求 (例如對於 DNS 或 syslog 這樣的無狀態協議)。 因爲套接字在服務重啓期間始終保持有效並且可被訪問, 同時所有客戶端請求也都被排入隊列等候處理。使用此機制之後, 守護進程必須要從 systemd 接收已創建好的套接字, 而不能自己創建並綁定套接字。 關於如何使用該機制,參見 sd_listen_fds(3) 與 sd-daemon(3) 手冊。 只需要小小的修改, 即可在原有啓動機制的基礎上添加基於套接字的啓動機制, 至於如何移植,詳見後文。
systemd 通過 .socket 單元實現該機制,詳見 systemd.socket(5) 手冊。 必須確保所有爲支持基於套接字啓動而創建的監聽 socket 單元都被包含在 sockets.target 中。 建議在 socket 單元的 "[Install]" 小節加入 WantedBy=sockets.target 設置, 以確保在啓用該單元時能夠自動添加上述依賴關係。 除非明確設置了 DefaultDependencies=no , 否則會爲所有 socket 單元隱含的創建必要的順序依賴。 有關 sockets.target 的解釋,詳見 systemd.special(7) 手冊。 如果某 socket 單元已被包含在 sockets.target 中, 那麼不建議在其中再添加任何額外的依賴關係(例如 multi-user.target 之類)。
基於 D-Bus 的啓動¶
如果守護進程使用 D-Bus 與客戶端通信, 那麼它應該使用基於 D-Bus 的啓動機制, 這樣當客戶端訪問其 D-Bus 接口時, 該服務將被自動啓動。 該機制是通過 D-Bus service 文件實現的(不要與普通的單元文件混淆)。 爲了確保讓 D-Bus 使用 systemd 來啓動與維護守護進程, 必須在這些 D-Bus service 文件中使用 SystemdService= 指明其匹配的服務單元。 例如,對於文件名爲 org.freedesktop.RealtimeKit.service 的 D-Bus service 來說, 爲了將其綁定到 rtkit-daemon.service 服務單元, 必須確保在該文件中設置了 SystemdService=rtkit-daemon.service 指令。 注意,必須明確設置 SystemdService= 指令, 否則當服務單元同時使用多種啓動機制時, 可能會導致競爭條件的出現。基於設備的啓動¶
用於管理特定類型硬件的守護進程, 只應該在符合條件的硬件變爲可用或者被插入時,才需要啓動。 爲了達到上述目的, 可以將服務的啓動/停止與硬件的插入/拔出事件綁定。 當帶有 "systemd" 標籤的設備出現在 sysfs/udev 設備樹中時, systemd 將會自動爲其創建對應的 device 單元。 通過向這些單元中添加對其他單元的 Wants= 依賴, 就可以實現當該 device 單元被啓動(也就是硬件被插入)時, 連帶啓動其他單元,從而實現基於設備的啓動。 這可以通過向 udev 規則庫中添加 SYSTEMD_WANTS= 屬性來實現, 詳見 systemd.device(5) 手冊。 通常,並不是將 service 單元直接添加到設備的 Wants= 依賴中, 而是通過專用的 target 單元間接添加。 例如,不是將 bluetoothd.service 添加到各種藍牙設備的 Wants= 依賴中, 而是將 bluetoothd.service 添加到 bluetooth.target 的 Wants= 依賴中, 同時再將 bluetooth.target 添加到各種藍牙設備的 Wants= 依賴中。 通過引入 bluetooth.target 這個抽象層, 系統管理員無需批量修改 udev 規則庫, 僅通過 systemctl enable|disable ... 命令 修改 bluetooth.target.wants/ 目錄中的軟鏈接, 即可控制 bluetoothd.service 的使用。基於路徑的啓動¶
對於處理 spool 文件或目錄的守護進程(例如打印服務)來說, 僅在 spool 文件或目錄狀態發生變化或者內容非空時, 才需要啓動。 通過 .path 單元實現的、 基於路徑的啓動機制正好適用於這種場合, 詳見 systemd.path(5) 手冊。基於定時器的啓動¶
對於週期性的操作(例如垃圾文件清理或者網絡對時), 可以通過基於定時器的啓動機制來實現。 這種機制通過 .timer 單元實現,詳見 systemd.timer(5) 手冊。其他啓動方式¶
在其他操作系統上還存在着其他的啓動機制, 不過這些機制都可以被前述的各種機制的組合替代。 因此在這裏不再贅述。與 SYSTEMD 整合¶
編寫 systemd 單元文件¶
在編寫單元文件時應當考慮下列建議:安裝 service 單元文件¶
當從源代碼編譯安裝(make install)軟件包時, 其中的系統服務單元文件會被默認安裝到 pkg-config systemd --variable=systemdsystemunitdir 命令返回的目錄中(通常是 /usr/lib/systemd/system); 而其中的用戶服務單元文件會被默認安裝到 pkg-config systemd --variable=systemduserunitdir 命令返回的目錄中(通常是 /usr/lib/systemd/user); 但並不應該使用 systemctl enable ... 命令啓用它們。 當從包管理器安裝(rpm -i)二進制軟件包時, 其中的單元文件應該同樣安裝到上述位置。 但不同之處在於, 還應該使用 systemctl enable ... 命令啓用它們, 因此安裝的單元有可能會在開機時自動啓動。移植已有的守護進程¶
雖然 systemd 兼容傳統的 SysV 初始化系統, 但是移植舊有的守護進程可以更好的利用 systemd 的先進特性。 建議對舊有的 SysV 守護進程做如下改進: ...[省略]...放置守護進程的數據¶
建議遵守 file-hierarchy(7) 所建議的通用準則。參見¶
systemd(1), sd-daemon(3), sd_listen_fds(3), sd_notify(3), daemon(3), systemd.service(5), file-hierarchy(7)NOTES¶
- 1.
- LSB recommendations for SysV init scripts
- 2.
- Apple MacOS X Daemon Requirements
跋¶
本頁面中文版由中文 man 手冊頁計劃提供。翻譯人員:金步國
金步國作品集:https://www.jinbuguo.com
中文 man
手冊頁計劃:../../man-pages-zh/manpages-zh
systemd 231 |