背景
自從服務器換成了 CentOS7 以后,經(jīng)常使用 systemctl 開頭的命令,比如啟動 Nginx 等服務的時候。但是并沒有深入了解該命令,經(jīng)常在碰到啟動失敗的時候不知道如何是好。
目標
- systemd 是什么;
- 為什么使用 systemd;
- systemctl 和 systemd 的關(guān)系;
- systemd 和 systemctl 的常用命令;
Systemd 是什么
以下為維基百科的定義:
systemd 是 Linux 操作系統(tǒng)下的一套中央化系統(tǒng)及設置管理程序(init 軟件),包括守護進程、程序庫和應用軟件,由 Lennart Poettering 帶頭開發(fā)。其開發(fā)目標是提供更優(yōu)秀的框架以表示系統(tǒng)服務間的依賴關(guān)系,并依此實現(xiàn)系統(tǒng)初始化時服務的并行啟動,同時達到降低 Shell 的系統(tǒng)開銷的效果,最終代替現(xiàn)在常用的System V 與 BSD 風格 init 程序。
通過以上定義可以看出,systems 是:
- 一套系統(tǒng)和服務管理器;
- 包含守護進程、程序庫和應用軟件;
為什么使用 systemd
systemd 出現(xiàn)以前
systemd 出現(xiàn)以前,一般都使用 Init 來啟動服務。以下為 Init 的定義:
init(為英語:initialization的簡寫)是 Unix 和 類Unix 系統(tǒng)中用來產(chǎn)生其它所有進程的程序。它以守護進程的方式存在,其進程號為1。Linux系統(tǒng)在開機時加載Linux內(nèi)核后,便由Linux內(nèi)核加載init程序,由init程序完成余下的開機過程,比如加載運行級別,加載服務,引導Shell/圖形化界面等等。
但在使用的過程中,Init 有兩個比較大的缺陷:
- 啟動時間長。init 進程是串行啟動,只有前一個進程啟動完,才會啟動下一個進程;
- 啟動腳本復雜。init 進程只是執(zhí)行啟動腳本,不管其他事情。腳本需要自己處理各種情況,這往往使得腳本變得很長;
在這樣的情況下,Linux 的各個發(fā)行版也嘗試過很多其他的系統(tǒng)和服務管理器,不過在 2015 年以后,Linux 的各個發(fā)行版都逐漸采用了 systemd。
為什么使用 systemd
systemd 就是為了解決這些問題而誕生的。它的設計目標是,為系統(tǒng)的啟動和管理提供一套完整的解決方案。
systemctl 和 systemd 的關(guān)系
systemd 的架構(gòu)

從上圖可以直觀地看出,systemctl 是 systemd 的眾多工具之一,而且是主要工具。
systemd 的各種工具
- systemd-analyze。用于查看啟動耗時;
- hostnamectl。用于查看當前主機信息;
- localectl。用于查看本地化設置;
- timedatectl。用于查看當前時區(qū)設置;
- loginctl。用于查看當前登陸的用戶;
Unit
定義
在 systemd 中,大多數(shù)操作的目標是 unit,它們是 systemd 知道如何管理的資源。
類型
unit 共有 12 種類型。詳見阮一峰的文章。
常用命令
# 列出所有 unit
$ systemctl list-units
# 查看系統(tǒng)狀態(tài)和單個 unit 的狀態(tài)
$ systemctl status
# 顯示某個 unit 是否正在運行
$ systemctl is-active application.service
# 顯示某個 unit 是否處于啟動失敗狀態(tài)
$ systemctl is-failed application.service
# 顯示某個 unit 服務是否建立了啟動鏈接
$ systemctl is-enabled application.service
# 立即啟動一個服務
$ sudo systemctl start apache.service
# 立即停止一個服務
$ sudo systemctl stop apache.service
# 重啟一個服務
$ sudo systemctl restart apache.service
# 殺死一個服務的所有子進程
$ sudo systemctl kill apache.service
# 重新加載一個服務的配置文件
$ sudo systemctl reload apache.service
# 重載所有修改過的配置文件
$ sudo systemctl daemon-reload
# 顯示某個 Unit 的所有底層參數(shù)
$ systemctl show httpd.service
# 顯示某個 Unit 的指定屬性的值
$ systemctl show -p CPUShares httpd.service
# 設置某個 Unit 的指定屬性
$ sudo systemctl set-property httpd.service CPUShares=500
依賴關(guān)系
# 列出所有依賴
$ systemctl list-dependencies nginx.service
配置文件
每一個 unit 都有一個配置文件,告訴 systemd 怎么啟動這個 unit 。
systemd 默認從目錄 /etc/systemd/system/ 讀取配置文件。但是,里面存放的大部分文件都是符號鏈接,指向目錄 /usr/lib/systemd/system/ ,真正的配置文件存放在那個目錄。
systemctl enable 命令用于在上面兩個目錄之間,建立符號鏈接關(guān)系。
$ sudo systemctl enable clamd@scan.service
# 等同于
$ sudo ln -s '/usr/lib/systemd/system/clamd@scan.service' '/etc/systemd/system/multi-user.target.wants/clamd@scan.service'
配置文件的后綴名,就是該 unit 的種類,比如 sshd.socket。如果省略,systemd 默認后綴名為 .service,所以 sshd 會被理解成sshd.service。
配置文件的格式
配置文件就是普通的文本文件,可以用文本編輯器打開。systemctl cat 命令可以查看配置文件的內(nèi)容。
$ systemctl cat nginx.service