寫在前面nginx
前文《開機流程分析》中講述在用戶層階段有對進程管理的工具備systemd和init兩種。在CentOS5,6上面使用init做爲進程管理的工具,在CentOS7 上面使用sytemd對進程進行管理,負責在系統啓動或運行時,激活系統資源,服務器進程和其它進程。因爲init對進程的管理方式以被人所熟知,因此本文主要講述Sytemd對進程的管理,以及兩者的在使用上的異同。
web
init侷限性centos
啓動時間長,init進程是串行啓動,只有前一個進程啓動完畢,纔會啓動下一個進程。bash
啓動腳本複雜。Init進程只是對執行進程啓動腳本,腳本須要處理各類狀況,進程若是有依賴性,腳本會變得很是複雜。服務器
Systemd的優缺點網絡
Systemd的設計目標是爲系統的啓動和管理提供一套完整的解決方案。Systemd的功能很是強大,使用也至關方便。可是它體系過於龐大,結構也很複雜。在軟件工程學中一直以高內聚,低耦合爲目標,systemd的設計反而和操做系統的各個層面是一種強耦合的關係。也不太符合keep simple, keep stupid的Linux哲學。session
System的的新特性socket
系統引導時實現服務並行啓動ide
按需啓動守護進程工具
自動化的服務依賴關係管理
同時採用socket 式與D-Bus 總線式激活服務
系統狀態快照
Systemd還有一個重要的特性是能夠兼容init對進程的管理方式,下降了工程師的學習成本。
unit 表示不一樣類型的systemd 對象,經過配置文件進行標識和配置;文件中主要包含了系統服務、監聽socket 、保存的系統快照以及其它與init 相關的信息
配置文件
/usr/lib/systemd/system: 每一個服務最主要的啓動腳本設置,相似於以前的/etc/init.d/ /run/systemd/system :系統執行過程當中所產生的服務腳本,比上面目錄優先運行 /etc/systemd/system :管理員創建的執行腳本,相似於/etc/rc.d/rcN.d/Sxx |
Unit分類
[root@centos7 ~]# systemctl -t help Available unit types: service socket busname target snapshot device mount automount swap timer path slice scope |
SysVinit中一般以runlevel的形式加載一組服務,在systemd啓動過程當中使用target取代runlevel,這也是啓動過程當中最大的變化。
sysVinit中定義了7種runlevel,0和6表示開機和重啓,1級別只包含一些必須啓動的服務,加載bash進程時不作身份校驗,通常用於維護和緊急的救援工做。2345級別雖然有系統自己對應的級別說明,可是用戶能夠更改其相應的配置文件來作定製化的配置。在配置服務過程當中,用戶須要本身解決服務的依賴關係,好比若是你要使用web服務,須要網絡服務的支持,因此web服務的啓動須要在network服務以後。這種依賴關係的判斷須要用戶按照本身的經驗來判斷,若是判斷失誤很是容易形成沒法啓動的狀況。
在systemd中默認使用了40多種target,當系統啓動時,會根據配置文件來肯定依賴關係並進行加載。下面是runlevel和target之間的對應表單:
SysVinit runlevel system target 0 runlevel0.target -> poweroff.target 1 runlevel1.target -> rescue.target 2 runlevel2.target -> multi-user.target 3 runlevel3.target -> multi-user.target 4 runlevel4.target -> multi-user.target 5 runlevel5.target -> graphical.target 6 runlevel6.target -> reboot.target |
能夠看出,在使用這5種targei來對應sysVinit中的7種運行級別,從而實現向後的兼容性問題。
打開任意一個target配置文件,裏面有一個很是重要的參數,關於依賴關係,即Requires/Wants關鍵字。Target或者各個unit之間的依賴關係有該關鍵字來確認。其中Requires表示強制依賴關係,Wangts表示非強制依賴關係。除了Wants和Requires以外還能夠有WantedBy、RequiredBy、Conflicts、ConglictedBy、Before、After等關鍵字來表示依賴與被依賴的關係。Systemd實現自動化解決依賴關係也是靠這些關鍵字來實現。只有當依賴的【unit】所有激活後,當前unit纔會被引導。每一個關鍵字表示的含義以下:
關鍵字 含義 Requires 強制依賴關係 Wants 非強制依賴關係,有依賴衝突時,暫時解除依賴關係 Before 引導順序,當前unit要在該值以前加載 After 引導順序,當前unit要在該值以後加載,與before相反 Conflicts 衝突關係 WantedBy unit爲service,弱依賴關係 RequiredBy unit爲service,強依賴關係 ConglictedBy |
上訴所說的依賴關係關鍵字都處於配置文件的unit小節,unit小節中除了依賴關係以外還有description關鍵字表示描述信息。除了unit小節外還有一個install小節,表示當前unit是否開機須要加載,和sysVinit的chkconfig on 設置開機自啓動的功能是相同的。第一個被引導的target必須設置爲Alias=default.target。
Unit的類型爲service時還有一個service小節,其中關鍵字也有不少,與服務啓動相關。
Type :定義影響ExecStart 及相關參數的功能的unit 進程啓動類型 simple :默認值,這個daemon 主要由ExecStart 接的指令串來啓動後常駐於內存中 forking :由ExecStart 啓動的程序透過spawns 延伸出其餘子程序來做爲此daemon 的主要服務。原生父程序在啓動結束後就會終止 oneshot :與simple 相似,不過這個程序在工做完畢後就結束了,不會常駐在內存中 dbus :與simple 相似,但這個daemon 必需要在取得一個D-Bus的 的名稱後,纔會繼續運做. 所以一般也要同時設定BusNname=才行 notify :在啓動完成後會發送一個通知消息。還須要配合 NotifyAccess 讓 來讓 Systemd 接收消息 idle :與simple 相似,要執行這個daemon 必需要全部的工做都順利執行完畢後纔會執行。這類的daemon 一般是開機到最後才執行便可的服務 EnvironmentFile :環境配置文件 ExecStart :指明啓動unit 要運行命令或腳本的絕對路徑 ExecStartPre: : ExecStart 前運行 ExecStartPost: : ExecStart 後運行 ExecStop :指明中止unit 要運行的命令或腳本 Restart :當設定Restart=1 時,則當次daemon 服務意外終止後,會再次自動啓動此服務 |
明白上述配置文件所表示的含義,我想用戶就能夠本身動手來跟蹤得出systemd的啓動流程了。CentOS7用戶層啓動流程以下:
內核初始化,執行initrd.target 全部單元,包括掛載/etc/fstab 從initramfs 根文件系統切換到磁盤根目錄 systemd執行默認target 配置,配置文件/etc/systemd/system/default.target systemd 執行sysinit.target 初始化系統及basic.target 準備操做系統 systemd 啓動multi-user.target 下的本機與服務器服務 systemd 執行multi-user.target 下的/etc/rc.d/rc.local Systemd 執行multi-user.target 下的getty.target 及登陸服務 systemd 執行graphical 須要的服務 |
運行級別之間的切換
[root@centos7 ~]# init 3 兼容sysVinit命令 ,切換至對應的multi-user模式 [root@centos7 ~]# systemctl isolate multi-user.target [root@centos7 ~]# systemctl get-default 獲取當前默認啓動的target [root@centos7 ~]# systemctl set-default multi-user.target 設置默認啓動的target 或者使用以下命令 [root@centos7 ~]# ln -sf /lib/systemd/system/multi-user.target /etc/systemd/system/default.target
|
Systemd把一些須要修改配置文件才能生效的功能也作成了新的命令,好比hostnamectl,localectl,loginctl,timedatectl等。
Systemctl命令,Systemd 的主命令,用於管理系統
[root@centos7 system]# systemctl reboot 重啓系統 [root@centos7 system]# systemctl poweroff 關閉系統,切斷電源 [root@centos7 system]# systemctl halt 關機不斷電源,至關於CPU不工做 [root@centos7 system]# systemctl suspend 暫停系統 [root@centos7 system]# systemctl rescue 進入救援模式(單用戶) |
Hostnamectl命令
[root@centos7 system]# hostnamectl 顯示當前主機信息 [root@centos7 system]# hostnamectl set-hostname www.zhyang.top 設置主機名 |
Localectl命令
[root@centos7 system]# localectl 查看系統當前字符集等信息 [root@centos7 system]# localectl list-locales 查看系統支持的字符集信息 [root@centos7 system]# localectl set-[keymap|locale|x11-keymap] … 設置系統使用的鍵盤佈局,字符集等 [root@centos7 system]# export.gbk 使設置的字符集生效 |
Loginctl命令
[root@centos7 ~]# loginctl list-sessions 列出當前會話 [root@centos7 ~]# loginctl list-users 列出當前登陸用戶 [root@centos7 ~]# loginctl show-user root 列出指定用戶的登陸信息 |
Timedatectl 命令
[root@centos7 ~]# timedatectl [status] 列出當前時間詳細信息 [root@centos7 ~]# timedatectl list-timezones 列出全部可用時區 [root@centos7 ~]# timedatectl set-timezones Asia/Shanghai 設置當前時區 [root@centos7 ~]# timedatectl set-time YYYY-MM-DD 設置時間 [root@centos7 ~]# timedatectl set-time HH:MM:SS [root@centos7 ~]# timedatectl set-ntp [yes|no] 開啓或關閉ntp服務 |
查看全部unit類型
[root@centos7 system]# systemctl -t help |
System 與sysVinit的服務對照表
Systemd Systemctl start [service] Systemctl stop [service] Systemctl enable [service] Systemctl disable [service] |
sysVinit service [service] start service [service] stop chkconfig [service] on chkconfig [service] on |
功能 當即運行某服務 當即中止某服務 開機啓動某服務 開機不啓動某服務 |
[root@centos7 ~]# systemctl status 顯示系統狀態和每一個unit狀態(樹形結構) [root@centos7 ~]# systemctl status [unit_name] 指定unit的狀態查看 [root@centos7 ~]# systemctl -H 172.18.250.194 status httpd 遠程查看某個主機的特定unit信息 [root@centos7 ~]# systemctl list-units -t service --state active 查看當前已激活的全部服務 [root@centos7 ~]# systemctl list-unit-files -t service --state [enabled] 查看系統開機啓動的服務信息
[root@centos7 ~]# systemctl kill [httpd.service] 殺死某個服務的全部子進程 [root@centos7 ~]# systemctl daemon-reload 重載全部修改的配置文件 [root@centos7 ~]# systemctl reload httpd.service 重載指定服務的配置文件 [root@centos7 ~]# systemctl mask httpd.service 禁止手動自動啓動某服務 [root@centos7 ~]# systemctl unmask httpd.service 取消禁止 |
依賴關係
[root@centos7 ~]# systemctl show -p "Wants" multi-user.target 查看target非強制依賴的服務 [root@centos7 ~]# systemctl show -p "Requires" multi-user.target 查看target強制依賴的服務 [root@centos7 ~]# systemctl list-dependencies httpd.service 列出一個unit的全部依賴 [root@centos7 ~]# systemctl list-dependencies --all httpd.service 更詳細列出全部依賴關係 |
[root@centos7 ~]# wget http://nginx.org/download/nginx-1.9.4.tar.gz [root@centos7 nginx-1.9.4]# tar -xf nginx-1.9.4.tar.gz [root@centos7 nginx-1.9.4]# cd nginx-1.9.4/ [root@centos7 nginx-1.9.4]# ./configure --prefix=/usr/local/nginx [root@centos7 nginx-1.9.4]# make [root@centos7 nginx-1.9.4]# make install [root@centos7 nginx-1.9.4]# cd /usr/lib/systemd/system [root@centos7 system]#cat >nginx.service<<EOF [Unit] Description=nginx - high performance web server Documentation=http://nginx.org/en/doc/ #After 參數設置啓動順序 After=network.target remote-fs.target nss-lookup.target
[Service] Type=forking PIDFile=/usr/local/nginx/logs/nginx.pid ExecStartPre=/usr/local/nginx/sbin/nginx -t #ExecStartPre參數可確保ExecStart參數啓動以前執行的命令,這裏啓動以前進行配置文件的正確性檢測 ExecStart=/usr/local/nginx/sbin/nginx #啓動Nginx服務 ExecReload=/bin/kill -s HUP $MAINPID #重載配置文件 ExecStop=/bin/kill -s QUIT $MAINPID #關閉Nginx服務 PrivateTmp=true
[Install] WantedBy=multi-user.target EOF [root@centos7 system]# systemctl daemon-reload [root@centos7 system]# systemctl status nginx.service [root@centos7 system]# systemctl start nginx.service |