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

編寫有趣且有價值的 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 知識星球   網站地圖