在linux下建立自定義服務
利用systemctl建立服務
歷史版本中的linux對服務的操作是通過service來完成的。若建立使用者自定義的服務,
則需要較為複雜的操作。目前linux新的發行版已經內建了systemctl來操作服務。
服務指令碼編寫
新的自定義服務指令碼以service為字尾,這些service檔案存放於/lib/systemd/system中。
我們只需要編寫符合標準規範的service指令碼檔案,放在這個資料夾下面即可。這個標準的服務檔案
格式如下:
2.png
三個部分
這個指令碼分為3個部分:[Unit] [Service] [Install]。
Unit
Unit表明該服務的描述,型別描述。我們稱之為一個單元。比較典型的情況是單元A要求在單元B啟動之後
在啟動。這種設定是通過Unit下面的Requires、After、Before、Wants
場景的編寫可以這樣(在A中編寫):
Requires=B
After=B
這段設定表明了A的啟動依賴於B,同時有要求在B啟動之後啟動自己。設定十分簡介。需要注意的是,
依賴關係通常用在服務(Service)而不是目標(Target)上。
Service
Service是指令碼的關鍵部分,這一部分用於設定一些關鍵引數:
Type=forking
: 後臺執行模式PIDFile=/xxx/xxx.xxx
: 存放PID檔案的位置ExecStart=/bin/echo xxx
: 這是服務執行的具體執行命令ExecReload=/bin/echo xxx
: 這是服務重啟的執行命令EexcStop=/bin/echo xxx
: 這是服務停止的執行命令
Service的啟動方式,在Service段中,啟動方式使用Type指定。具體可以參考man systemd.service
。
值得注意的是,在指令碼中關於服務啟動、重啟、關閉的指令需要使用絕對路徑,否則會出現無法識別的情況。
當完成一個服務指令碼後,我們就可以使用systemctl start|stop|restart xxx.service等指令了。
若要開機啟動這個服務:
systemctl enable xxx.service
若要關閉開機啟動:
systemctl disable xxx.service
當我們需要檢視服務資訊的使用可以使用如下指令:
systemctl list-units --type=service
: 列出正在執行的服務
在service片段中有幾個概念很重要,這直接影響到實踐中建立自定義服務的最終結果。以下內容根據linux系統
中man systemd.service
使用者手冊說明經過翻譯和整理而得。
service配置之Type
首先是Type配置,在service片段中有Type的配置,這個配置給當前的服務單元用於設定程序的啟動型別。
Type有如下幾種可選項:
simple
forking
oneshot
dbus
notify
idel
simple,這是預設的Type,當Type和BusName配置都沒有設定,指定了ExecStart設定後,simple就是
預設的Type設定。simple使用ExecStart建立的程序作為服務的主程序。在此設定下systemd會立即啟動服務,如果該服務要
啟動其他服務(simple不會forking),它們的通訊渠道應當在守護程序啟動之前被安裝好(e.g. sockets,通過sockets啟用)。
forking,如果使用了這個Type,則ExecStart的指令碼啟動後會呼叫fork()函式建立一個程序作為其啟動的一部分。
當一切初始化完畢後,父程序會退出。子程序會繼續作為主程序執行。這是傳統UNIX主程序的行為。如果這個設定被指定,
建議同時設定PIDFile選項來指定pid檔案的路徑,以便systemd能夠識別主程序。
oneshot,onesh的行為十分類似simple,但是,在systemd啟動之前,程序就會退出。這是一次性的行為。
可能還需要設定RemainAfterExit=yes,以便systemd認為j程序退出後仍然處於啟用狀態。
dbus,這個設定也和simple很相似,該配置期待或設定一個name值,通過設定BusName=設定name即可。
notify,同樣地,與simple相似的配置。顧名思義,該設定會在守護程序啟動的時候傳送推送訊息(通過sd_notify(3))給systemd。
Service其他配置節點
RemainAfterExit
:預設值no
預設值為no,這個設定採用booleean值,可以是0、no、off、1、yes、on等值。
它表明服務是否應當被視為啟用的,即便當它所有的程序都退出了。簡言之,這個設定用於告訴systemd服務是否
應當是被視為啟用狀態,而不管程序是否退出。當為true時,即便服務退出,systemd依然將這個服務視為啟用狀態,
反之則服務停止。
GuessMainPID
採用boolean值指定systemd在無法確切的查明服務的時候是否需要猜測服務的main pid。
除非Type=forking
被採用並且PIDFile沒有被設定,否則這個選項會被忽略。因為當設定為Type的其他
選項,或者顯示的指定了PID檔案後,systemd總是能夠知道main pid。
PIDFile
採用一個絕對路徑的檔名指定守護程序的PID檔案。當Type=forking被設定的時候,建議採取這個設定。
當服務啟動後,systemd會讀取守護程序的主程序id。systemd不會對該檔案寫入資料。
BusName
使用一個D-Bus的匯流排名稱,作為該服務的可訪問名稱。當Type=dbus
的時候,該設定被強制使用。
BusPolicy
如果該選項被指定,一個自定義的kdbus終結點將會被建立,並且會被指定為預設的dbus節點安裝到服務上。
這樣的自定義終結點自身持有一個策略規則集合。這些規則將會在匯流排範圍內被強制指定。該選項只有在kdbus被啟用時有效。
ExecStart
當服務啟動的時候(systemctl start youservice.service
),會執行這個選項的值,
這個值一般是“ExecStart=指令 引數”
的形式。當Type=oneshot
的時候,只有一個指令可以並且必須給出。
原因是oneshot只會被執行一次。
ExecStartPre
、ExecStartPost
顧名思義,這兩個設定的意義在於ExecStart
被執行之前和之後被執行。
ExecReload
服務重啟時執行。
ExecStop
服務停止時執行。
ExecStopPost
服務停止後執行。
未完待續...