Systemd
Systemd(system daemon)實現系統服務間的依賴關系,並依此實現系統初始化時服務的並行啟動,同時達到降低Shell的系統開銷,最終替代init。
Systemd采用了一下新技術:
-
采用Socket激活式與總線激活式服務,以提高相互依賴的各服務的並行運行性能。
-
采用Cgroups替代PID來追蹤進程,即使是兩次fork之后生成的守護進程也不會脫離systemd的控制。
Systemd Unit
學習Systemd的第一步,就是搞懂 Unit(單元)是什么?
Unit就是Systemd的最小 功能/管理 單位,是單個進程的描述。一個個小的Unit相互調用和依賴,組成一個龐大的任務管理系統,這就是Systemd的基本思想。
由於Systemd要做到事情太多,導致Unit有很多種不同的類型:
-
Service Unit - 用於定義系統服務
-
Target Unit - 用於模擬實現“運行級別”
-
Socket Unit - 用於Systemd監聽Socket,在有連接的時候再啟動。
-
Device Unit - 用於定義內核識別的設備
-
Mount Unit - 用於定義文件系統掛載
-
Snapshot Unit - 用於管理系統快照
-
Swap Unit - 用於標識swap設備
-
Automount Unit - 用於文件系統自動掛載
-
Path Unit - 用於定義文件系統中的文件或目錄
所有的Unit文件都存放在 /usr/lib/systemd/system和/etc/systemd/system
-
-
通常由三部分組成,[Unit] [Service] [Install],各部分釋義:
[Unit] 段的常用選項: Description:描述信息; 意義性描述; After:定義unit的啟動次序,表示當前unit應該晚於哪些unit啟動;其功能與Before相反; Requies:依賴到的其它units;強依賴,被依賴的units無法激活時,當前unit即無法激活; Wants:依賴到的其它units;弱依賴; Conflicts:定義units間的沖突關系
[Service] 段的常用選項: Type:用於定義影響ExecStart及相關參數的功能的unit進程啟動類型,其類型有: simple:默認值,執行ExecStart指定的命令,啟動主進程 forking:以 fork 方式從父進程創建子進程,創建后父進程會立即退出 oneshot:一次性進程,Systemd 會等當前服務退出,再繼續往下執行 dbus:當前服務通過D-Bus啟動 notify:當前服務啟動完畢,會通知systemd再繼續往下執行 idle:若有其他任務執行完畢,當前服務才會運行 EnvironmentFile:環境配置文件; ExecStart:指明啟動unit要運行命令或腳本; ExecStartPre:在ExecStart之前運行; ExecStartPost:在ExecStart之后運行; ExecReload: 指明重新加載配置的命令或腳本; #示例 ExecReload=/bin/kill -HUP $MAINPID ExecStop:指明停止unit要運行的命令或腳本; Restart:當設定Restart=1時,則當次daemon服務意外終止后,會再次自動啟動。 [Install] 段的常用選項: Alias:別名,可使用systemctl command Alias.service; RequiredBy:被哪些units所依賴; WantedBy:被哪些units所依賴 注意:對於新建或修改unit文件,需要通過命令 systemctl daemon-reload 重新加載。
- Service Unit只是定義了如何執行任務,還必須通過Timer Unit定義執行時間,示例:
**定義Timer調用的my-timer.service ** [Unit] Description = MyTimer [Service] ExecStart = /bin/echo "...Hello MyTimer..."
**定義調用Service的my-timer.timer** [Unit] Description = Runs mytimer every minutes [Timer] OnUnitActiveSec = 1m Unit = mytimer.service [Install] WantedBy = multi-user.target
# [Timer] 字段
OnActiveSec:定時器生效后,多少時間開始執行任務
OnBootSec:系統啟動后,多少時間開始執行任務
OnStartupSec:Systemd 進程啟動后,多少時間開始執行任務
OnUnitActiveSec:該單元上次執行后,等多少時間再次執行
OnUnitInactiveSec: 定時器上次關閉后多少時間,再次執行
OnCalendar:基於絕對時間,而不是相對時間執行
AccuracySec:如果因為各種原因,任務必須推遲執行,推遲的最大秒數,默認是60秒
Unit:真正要執行的任務,默認是同名的帶有.service后綴的單元
Persistent:如果設置了該字段,即使定時器到時沒有啟動,也會自動執行相應的單元
WakeSystem:如果系統休眠,是否自動喚醒系統
Socket Unit
-
以 "
.socket
" 為后綴的單元文件, 封裝了一個用於進程間通信的套接字(socket)或管道(FIFO), 以支持基於套接字的啟動。 -
讓Systemd監聽Socket,在有連接的時候再啟動該Unit,需要同名的Service。
- 可以查看系統自帶的sshd.socket示例。
Target Unit
-
Target是指一組相關進程,有點像init進程模式下面的啟動級別。
-
當WantedBy設置為指定target時,執行systemctl enable/disable [UnitName]時,會自動創建軟連接到/usr/lib/systemd/system下對應的target.wants目錄中
-
可以通過 systemctl get-default 查看當前運行級別。
- Target 與 傳統 RunLevel 的對應關系如下:
- Runlevel 0 == poweroff.target
- Runlevel 1 == rescue.target
- Runlevel 2 == multi-user.target
- Runlevel 3 == multi-user.target
- Runlevel 4 == multi-user.target
- Runlevel 5 == graphical.target
- Runlevel 6 == reboot.target
Systemd Command
# 查看單元狀態 ## active (running): 進程持續的運行中 ## active (exited): 進程成功完成一次執行 ## active (waiting): 進程等待中 ## inactive: 未運行 $ systemctl status [UnitName] # 查看是否已啟用該單元 ## enable、disable或static ## static是指對應的Unit文件中沒有定義[Install]區域,因此無法配置為開機啟動服務。 $ systemctl is-enabled [UnitName] # 開機自動執行該單元 $ systemctl enable [UnitName] # 關閉開機自動執行 $ systemctl disable [UnitName] # 啟動單元 $ systemctl start [UnitName] # 關閉單元 $ systemctl stop [UnitName] # 重啟單元 $ systemctl restart [UnitName] # 重新加載服務配置,而不中斷服務 $ systemctl reload [UnitName] # 類似於 nginx -s reload # 殺死單元進程 $ systemctl kill [UnitName] # 禁止服務,無法啟動或開機啟動 $ systemctl mask [UnitName] # List units that systemd currently has in memory. $ systemctl list-units # List unit files installed on the system, in combination with their enablement state (as reported by is-enabled). $ systemctl list-unit-files # Shows units required and wanted by the specified unit. $ systemctl list-dependencies
Systemd 架構圖