編寫systemctl自啟動服務


Systemd簡介

Centos7 以上使用Systemd進行系統初始化,Systemd是Linux系統中最新的初始化工具,它可以有效的提高系統的啟動速度。

Systemd 默認從目錄/etc/systemd/system/讀取配置文件。然而,里面存放的大部分文件都是符號鏈接,它們指向目錄/usr/lib/systemd/system/,真正的配置文件(以 .service 結尾的文件)存放在那個目錄。

我們可以將自定義程序注冊為systemd service進程管理交給系統管理,可以方便啟動停止,也可以實現服務異常退出重啟,開機自啟動,減少自定義程序服務管理的時間消耗。

Systemd配置與命令

service文件參數詳解

service文件主要包含三個部分,分別是:[Unit]、[Service]、[Install]

如以下的nginx.service配置文件

# 配置文件內容
[Unit]                                          
Description=nginx 
After=network.target 
 
[Service] 
Type=forking 
ExecStart=/usr/local/nginx/sbin/nginx 
ExecReload=/usr/local/nginx/sbin/nginx -s reload 
ExecStop=/usr/local/nginx/sbin/nginx -s quit
PrivateTmp=true 
 
[Install] 
WantedBy=multi-user.target

參數說明如下

參數名稱 參數說明
[Unit]
Description 一段描述這個 Unit 文件的文字,通常只是簡短的一句話。
Documentation 指定服務的文檔,可以是一個或多個文檔的URL路徑。
Requires 依賴的其他 Unit 列表,列在其中的 Unit 模塊會在這個服務啟動的同時被啟動,並且如果其中有任意一個服務啟動失敗,這個服務也會被終止
After 與 Requires 相似,但會在后面列出的所有模塊全部啟動完成以后,才會啟動當前的服務。
Before 與 After 相反,在啟動指定的任一個模塊之前,都會首先確保當前服務已經運行。
Wants 與 Requires 相似,但只是在被配置的這個 Unit 啟動時,觸發啟動列出的每個 Unit 模塊,而不去考慮這些模塊啟動是否成功。
Conflicts 與這個模塊有沖突的模塊,如果列出模塊中有已經在運行的,這個服務就不能啟動,反之亦然。
OnFailure 當這個模塊啟動失敗時,就自動啟動列出的每個模塊。
[Service]
Type 服務的類型,常用的有 simple(默認類型) 和 forking。默認的 simple 類型可以適應於絕大多數的場景,因此一般可以忽略這個參數的配置。而如果服務程序啟動后會通過 fork 系統調用創建子進程,然后關閉應用程序本身進程的情況,則應該將 Type 的值設置為 forking,否則 systemd 將不會跟蹤子進程的行為,而認為服務已經退出。
Environment 為服務添加環境變量
EnvironmentFile 指定加載一個包含服務所需的環境變量列表的文件,文件中的每一行都是一個環境變量的定義。
ExecStart 這個參數是幾乎每個 .service 文件都會有的,指定服務啟動的主要命令,在每個配置文件中只能使用一次。(需要使用絕對路徑)
ExecStartPre 指定在啟動執行 ExecStart 的命令前的准備工作,可以有多個,所有命令會按照文件中書寫的順序依次被執行。
ExecStartPost 指定在啟動執行 ExecStart 的命令后的收尾工作,也可以有多個。
ExecStop 停止服務所需要執行的主要命令。(需要使用絕對路徑)
ExecStopPost 指定在 ExecStop 命令執行后的收尾工作,也可以有多個。
ExecReload 重新加載服務所需執行的主要命令。(需要使用絕對路徑)
Restart 這個值用於指定在什么情況下需要重啟服務進程。常用的值有 no,on-success,on-failure,on-abnormal,on-abort 和 always。默認值為 no,即不會自動重啟服務。這些不同的值分別表示了在哪些情況下,服務會被重新啟動
RestartSec 如果服務需要被重啟,這個參數的值為服務被重啟前的等待秒數。
Nice 服務的進程優先級,值越小優先級越高,默認為0。-20為最高優先級,19為最低優先級。
WorkingDirectory 指定服務的工作目錄。
RootDirectory 指定服務進程的根目錄( / 目錄),如果配置了這個參數后,服務將無法訪問指定目錄以外的任何文件。
User 指定運行服務的用戶,會影響服務對本地文件系統的訪問權限。
Group 指定運行服務的用戶組,會影響服務對本地文件系統的訪問權限。
PrivateTmp 是否給服務分配獨立的臨時空間(true/false)
[Install]
WantedBy 和前面的 Wants 作用相似,只是后面列出的不是服務所依賴的模塊,而是依賴當前服務的模塊。“WantedBy=multi-user.target” 表明當系統以多用戶方式(默認的運行級別)啟動時,這個服務需要被自動運行。當然還需要 systemctl enable 激活這個服務以后自動運行才會生效。
RequiredBy 和前面的 Requires 作用相似,同樣后面列出的不是服務所依賴的模塊,而是依賴當前服務的模塊。
Also 當這個服務被 enable/disable 時,將自動 enable/disable 后面列出的每個模塊。

注意:[Service]的啟動、重啟、停止命令全部要求使用絕對路徑

想了解更詳細的參數說明可以在systemd.service 中文手冊中查看

systemctl常用命令

以nginx.service為例

# 啟動nginx服務
systemctl start nginx.service
# 停止nginx服務
systemctl stop nginx.service
# 重啟nginx服務
systemctl restart nginx.service
# 查看nginx服務狀態
systemctl status nginx.service
# 在開機時啟用一個服務
systemctl enable nginx.service
# 在開機時禁用一個服務
systemctl disable nginx.service
# 查看服務是否開機啟動
systemctl is-enabled nginx.service
# 重新讀取nginx配置(不用停止nginx服務就能使修改的配置生效)
systemctl reload nginx.service
# 重新加載systemd(一般修改完配置文件執行該命令使配置生效)
systemctl daemon-reload
# 查看已啟動的服務列表
systemctl list-unit-files | grep enabled
# 查看啟動失敗的服務列表
systemctl --failed

其中,systemctl enable命令用於/etc/systemd/system//usr/lib/systemd/system/兩個目錄之間,建立符號鏈接關系。

systemctl enable nginx.service
# 等同於
ln -s '/usr/lib/systemd/system/nginx.service' '/etc/systemd/system/multi-user.target.wants/nginx.service'

systemd 默認從目錄/etc/systemd/system/讀取配置文件,所以systemctl enable命令相當於激活開機啟動。

同理,systemctl disable用於撤銷兩個目錄之間的符號鏈接關系,也就撤銷了開機啟動。

編寫systemd自啟動服務

在上面內容的基礎下,我們嘗試編寫一個自己的systemd服務,本次的systemd服務主要是執行一段python腳本。

在/root/pyfile路徑(這里可以改為你自己的路徑)下創建run.py,內容如下

import time
import string
import random

f = open('/root/pyfile/a.txt', 'w')
for i in range(100):
    words = ''.join(random.sample(string.ascii_lowercase, 5))
    row = '--- No.{}, {} ---\n'.format(i, words)
    f.write(row)
    f.flush()
    time.sleep(2)

f.close()

以上腳本的作用是在100次遍歷中,每2s生成一個隨機的單詞,並將單詞寫入到a.txt中。

接下來我們來編寫自定義的systemd服務,在/usr/lib/systemd/system路徑下新建pyscript.service服務,內容如下

[Unit]
Description=python script

[Service]
Type=simple
WorkingDirectory=/root/pyfile
ExecStart=python run.py

[Install]
WantedBy=multi-user.target

編寫完成后,保存並執行以下命令

systemctl daemon-reload
systemctl start pyscript.service

進入/root/pyfile目錄下執行tail -f a.txt可以看出每2s打印一個隨機單詞,如下

--- No.0, jkqdr ---
--- No.1, beqvu ---
--- No.2, eaqrw ---
--- No.3, kuljf ---
--- No.4, qmzhl ---

接下來我們設置開機啟動pyscript.service服務

systemctl start pyscript.service

執行后系統生成了一個符號鏈接,如下

Created symlink /etc/systemd/system/multi-user.target.wants/pyscript.service → /usr/lib/systemd/system/pyscript.service.

然后重啟服務器,等待重啟完畢后,執行以下命令查看python腳本是否執行

ps -ef | grep python

可以發現多了如下進程

root   738  1  0 18:00 ?    00:00:00 /usr/bin/python run.py

再次進入/root/pyfile目錄,執行tail -f a.txt,可以發現文本正在打印。

自此,我們已經成功完成了自定義systemd服務的編寫和啟動。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM