歡迎光臨
每天分享高質量文章

編寫有趣且有價值的 Systemd 服務 | Linux 中國

每次開機之後需要啟動服務器,每次關機之前需要安全地關閉服務行程,十分繁瑣和麻煩。
— Paul Brown


致謝
編譯自 | https://www.linux.com/blog/learn/intro-to-linux/2018/5/writing-systemd-services-fun-and-profit 
 作者 | Paul Brown
 譯者 | Andy Song (pinewall) ? ? ? 共計翻譯:16 篇 貢獻時間:66 天

讓我們假設你希望搭建一個游戲服務器,運行 Minetest[1] 這款非常酷、開源的,以採集 & 合成為主題的沙盒游戲。你希望將游戲運行在位於客廳的服務器中,以便搭建完成後可供你的學校或朋友使用。你知道內核郵件串列的管理就不過就是如此,那麼對你來說也是足夠的。

但你很快發現每次開機之後需要啟動服務行程,每次關機之前需要安全地關閉服務器,十分繁瑣和麻煩。

最初,你可能用守護行程的方式運行服務器:

  1. minetest --server &

記住行程 PID 以便後續使用。

接著,你還需要通過郵件或短信的方式將服務器已經啟動的信息告知你的朋友。然後你就可以開始游戲了。

轉眼之間,已經凌晨三點,今天的戰鬥即將告一段落。但在你關閉主機、睡個好覺之前,還需要做一些操作。首先,你需要通知其它玩家服務器即將關閉,找到記錄我們之前提到的 PID 的紙條,然後友好地關閉 Minetest 服務行程。

  1. kill -2 <PID>

這是因為直接關閉主機電源很可能導致檔案損壞。下一步也是最後一步,關閉主機電源。

一定有方法能讓事情變得更簡單。

讓 Systemd 服務拯救你

讓我們從構建一個普通用戶可以(手動)運行的 systemd 服務開始,然後再逐步增加內容。

不需要管理員權限即可運行的服務位於 ~/.config/systemd/user/,故首先需要創建這個目錄:

  1. cd

  2. mkdir -p ~/.config/systemd/user/

有很多型別的 systemd 單元 (曾經叫做 systemd 腳本),包括“計時器”和“路徑”等,但我們這裡關註的是“服務”型別。在 ~/.config/systemd/user/ 目錄中創建 minetest.service 檔案,使用文本編輯器打開並輸入如下內容:

  1. # minetest.service

  2. [Unit]

  3. Description= Minetest server

  4. Documentation= https://wiki.minetest.net/Main_Page

  5. [Service]

  6. Type= simple

  7. ExecStart= /usr/games/minetest --server

可以看到該單元中包含不同的段,其中 [Unit] 段主要為用戶提供信息,給出該單元的描述及如何獲得更多相關文件。

腳本核心位於 [Service] 段,首先使用 Type 指令確定服務型別。服務有多種型別[2],下麵給出兩個示例。如果你運行的行程設置環境變數、呼叫另外一個行程(主行程)、退出運行,那麼你應該使用的服務型別為 forking。如果你希望在你的單元對應行程結束運行前阻斷其他單元運行,那麼你應該使用的服務型別為 oneshot

但 Minetest 服務器的情形與上面兩種都不同,你希望啟動服務器並使其在後臺持續運行;這種情況下應該使用 simple 型別。

下麵來看 ExecStart 指令,它給出 systemd 需要運行的程式。在本例中,你希望在後臺運行 minetest 服務器。如上所示,你可以在可執行程式後面添加引數,但不能將一系列 Bash 命令通過管道連接起來。下麵給出的例子無法工作:

  1. ExecStart: lsmod | grep nvidia > videodrive.txt

如果你需要將 Bash 命令通過管道連接起來,可以將其封裝到一個腳本中,然後運行該腳本。

還需要註意一點,systemd 要求你給出程式的完整路徑。故如果你想使用 simple 型別運行類似 ls 的命令,你需要使用 ExecStart= /bin/ls

另外還有 ExecStop 指令用於定製服務終止的方式。我們會在第二部分討論這個指令,但你要瞭解,如果你沒有指定 ExecStop,systemd 會幫你盡可能友好地終止行程。

systemd.directives 的幫助頁中包含完整指令串列,另外你可以在該網站[3]上找到同樣的串列,點擊即可查看每個指令的具體信息。

雖然只有 6 行,但你的 minetest.service 已經是一個有完整功能的 systemd 單元。執行如下命令啟動服務:

  1. systemd --user start minetest

執行如下命令終止服務:

  1. systemd --user stop minetest

選項 --user 告知 systemd 在你的本地目錄中檢索服務並用你的用戶權限執行服務。

我們的服務器管理故事到此完成了第一部分。在第二部分,我們將在啟動和終止服務的基礎上,學習如何給用戶發郵件、告知用戶服務器的可用性。敬請期待。

可以通過 Linux 基金會和 edX 的免費課程 “Linux 入門[4]”學習更多 Linux 知識。


via: https://www.linux.com/blog/learn/intro-to-linux/2018/5/writing-systemd-services-fun-and-profit

作者:Paul Brown[6] 選題:lujun9972 譯者:pinewall 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出

赞(0)

分享創造快樂

© 2022 知識星球   网站地图