Linux系統(tǒng)的啟動(dòng)方式有點(diǎn)復(fù)雜,而且總是有需要優(yōu)化的地方。傳統(tǒng)的Linux系統(tǒng)啟動(dòng)過(guò)程主要由著名的init進(jìn)程(也被稱為SysV init啟動(dòng)系統(tǒng))處理,而基于init的啟動(dòng)系統(tǒng)被認(rèn)為有效率不足的問(wèn)題,systemd是Linux系統(tǒng)機(jī)器的另一種啟動(dòng)方式,宣稱彌補(bǔ)了以傳統(tǒng)Linux SysV init為基礎(chǔ)的系統(tǒng)的缺點(diǎn)。在這里我們將著重討論systemd的特性和爭(zhēng)議,但是為了更好地理解它,也會(huì)看一下通過(guò)傳統(tǒng)的以SysV init為基礎(chǔ)的系統(tǒng)的Linux啟動(dòng)過(guò)程是什么樣的。友情提醒一下,systemd仍然處在測(cè)試階段,而未來(lái)發(fā)布的Linux操作系統(tǒng)也正準(zhǔn)備用systemd啟動(dòng)管理程序替代當(dāng)前的啟動(dòng)過(guò)程(LCTT 譯注:截止到本文發(fā)表,主流的Linux發(fā)行版已經(jīng)有很多采用了 systemd)。
理解Linux啟動(dòng)過(guò)程
在我們打開(kāi)Linux電腦的電源后第一個(gè)啟動(dòng)的進(jìn)程就是init。分配給init進(jìn)程的PID是1。它是系統(tǒng)其他所有進(jìn)程的父進(jìn)程。當(dāng)一臺(tái)Linux電腦啟動(dòng)后,處理器會(huì)先在系統(tǒng)存儲(chǔ)中查找BIOS,之后BIOS會(huì)檢測(cè)系統(tǒng)資源然后找到第一個(gè)引導(dǎo)設(shè)備,通常為硬盤,然后會(huì)查找硬盤的主引導(dǎo)記錄(MBR),然后加載到內(nèi)存中并把控制權(quán)交給它,以后的啟動(dòng)過(guò)程就由MBR控制。
主引導(dǎo)記錄會(huì)初始化引導(dǎo)程序(Linux上有兩個(gè)著名的引導(dǎo)程序,GRUB和LILO,80%的Linux系統(tǒng)在用GRUB引導(dǎo)程序),這個(gè)時(shí)候GRUB或LILO會(huì)加載內(nèi)核模塊。內(nèi)核會(huì)馬上查找/sbin下的“init”程序并執(zhí)行它。從這里開(kāi)始init成為了Linux系統(tǒng)的父進(jìn)程。init讀取的第一個(gè)文件是/etc/inittab,通過(guò)它init會(huì)確定我們Linux操作系統(tǒng)的運(yùn)行級(jí)別。它會(huì)從文件/etc/fstab里查找分區(qū)表信息然后做相應(yīng)的掛載。然后init會(huì)啟動(dòng)/etc/init.d里指定的默認(rèn)啟動(dòng)級(jí)別的所有服務(wù)/腳本。所有服務(wù)在這里通過(guò)init一個(gè)一個(gè)被初始化。在這個(gè)過(guò)程里,init每次只啟動(dòng)一個(gè)服務(wù),所有服務(wù)/守護(hù)進(jìn)程都在后臺(tái)執(zhí)行并由init來(lái)管理。
關(guān)機(jī)過(guò)程差不多是相反的過(guò)程,首先init停止所有服務(wù),最后階段會(huì)卸載文件系統(tǒng)。
以上提到的啟動(dòng)過(guò)程有一些不足的地方。而用一種更好的方式來(lái)替代傳統(tǒng)init的需求已經(jīng)存在很長(zhǎng)時(shí)間了。也產(chǎn)生了許多替代方案。其中比較著名的有Upstart,Epoch,Muda和Systemd。而Systemd獲得最多關(guān)注并被認(rèn)為是目前最佳的方案。
理解Systemd
開(kāi)發(fā)Systemd的主要目的就是減少系統(tǒng)引導(dǎo)時(shí)間和計(jì)算開(kāi)銷。Systemd(系統(tǒng)管理守護(hù)進(jìn)程),最開(kāi)始以GNU GPL協(xié)議授權(quán)開(kāi)發(fā),現(xiàn)在已轉(zhuǎn)為使用GNU LGPL協(xié)議,它是如今討論最熱烈的引導(dǎo)和服務(wù)管理程序。如果你的Linux系統(tǒng)配置為使用Systemd引導(dǎo)程序,它取替?zhèn)鹘y(tǒng)的SysV init,啟動(dòng)過(guò)程將交給systemd處理。Systemd的一個(gè)核心功能是它同時(shí)支持SysV init的后開(kāi)機(jī)啟動(dòng)腳本。
Systemd引入了并行啟動(dòng)的概念,它會(huì)為每個(gè)需要啟動(dòng)的守護(hù)進(jìn)程建立一個(gè)套接字,這些套接字對(duì)于使用它們的進(jìn)程來(lái)說(shuō)是抽象的,這樣它們可以允許不同守護(hù)進(jìn)程之間進(jìn)行交互。Systemd會(huì)創(chuàng)建新進(jìn)程并為每個(gè)進(jìn)程分配一個(gè)控制組(cgroup)。處于不同控制組的進(jìn)程之間可以通過(guò)內(nèi)核來(lái)互相通信。systemd處理開(kāi)機(jī)啟動(dòng)進(jìn)程的方式非常漂亮,和傳統(tǒng)基于init的系統(tǒng)比起來(lái)優(yōu)化了太多。讓我們看下Systemd的一些核心功能。
和init比起來(lái)引導(dǎo)過(guò)程簡(jiǎn)化了很多
Systemd支持并發(fā)引導(dǎo)過(guò)程從而可以更快啟動(dòng)
通過(guò)控制組來(lái)追蹤進(jìn)程,而不是PID
優(yōu)化了處理引導(dǎo)過(guò)程和服務(wù)之間依賴的方式
支持系統(tǒng)快照和恢復(fù)
監(jiān)控已啟動(dòng)的服務(wù);也支持重啟已崩潰服務(wù)
包含了systemd-login模塊用于控制用戶登錄
支持加載和卸載組件
低內(nèi)存使用痕跡以及任務(wù)調(diào)度能力
記錄事件的Journald模塊和記錄系統(tǒng)日志的syslogd模塊
Systemd同時(shí)也清晰地處理了系統(tǒng)關(guān)機(jī)過(guò)程。它在/usr/lib/systemd/目錄下有三個(gè)腳本,分別叫systemd-halt.service,systemd-poweroff.service,systemd-reboot.service。這幾個(gè)腳本會(huì)在用戶選擇關(guān)機(jī),重啟或待機(jī)時(shí)執(zhí)行。在接收到關(guān)機(jī)事件時(shí),systemd首先卸載所有文件系統(tǒng)并停止所有內(nèi)存交換設(shè)備,斷開(kāi)存儲(chǔ)設(shè)備,之后停止所有剩下的進(jìn)程。
Systemd結(jié)構(gòu)概覽
讓我們看一下Linux系統(tǒng)在使用systemd作為引導(dǎo)程序時(shí)的開(kāi)機(jī)啟動(dòng)過(guò)程的結(jié)構(gòu)性細(xì)節(jié)。為了簡(jiǎn)單,我們將在下面按步驟列出來(lái)這個(gè)過(guò)程:
1.?當(dāng)你打開(kāi)電源后電腦所做的第一件事情就是BIOS初始化。BIOS會(huì)讀取引導(dǎo)設(shè)備設(shè)定,定位并傳遞系統(tǒng)控制權(quán)給MBR(假設(shè)硬盤是第一引導(dǎo)設(shè)備)。
2.?MBR從Grub或LILO引導(dǎo)程序讀取相關(guān)信息并初始化內(nèi)核。接下來(lái)將由Grub或LILO繼續(xù)引導(dǎo)系統(tǒng)。如果你在grub配置文件里指定了systemd作為引導(dǎo)管理程序,之后的引導(dǎo)過(guò)程將由systemd完成。Systemd使用“target”來(lái)處理引導(dǎo)和服務(wù)管理過(guò)程。這些systemd里的“target”文件被用于分組不同的引導(dǎo)單元以及啟動(dòng)同步進(jìn)程。
3.?systemd執(zhí)行的第一個(gè)目標(biāo)是default.target。但實(shí)際上default.target是指向graphical.target的軟鏈接。Linux里的軟鏈接用起來(lái)和Windows下的快捷方式一樣。文件Graphical.target的實(shí)際位置是/usr/lib/systemd/system/graphical.target。在下面的截圖里顯示了graphical.target文件的內(nèi)容。
4.?在這個(gè)階段,會(huì)啟動(dòng)multi-user.target而這個(gè)target將自己的子單元放在目錄“/etc/systemd/system/multi-user.target.wants”里。這個(gè)target為多用戶支持設(shè)定系統(tǒng)環(huán)境。非root用戶會(huì)在這個(gè)階段的引導(dǎo)過(guò)程中啟用。防火墻相關(guān)的服務(wù)也會(huì)在這個(gè)階段啟動(dòng)。
"multi-user.target"會(huì)將控制權(quán)交給另一層“basic.target”。
5.?"basic.target"單元用于啟動(dòng)普通服務(wù)特別是圖形管理服務(wù)。它通過(guò)/etc/systemd/system/basic.target.wants目錄來(lái)決定哪些服務(wù)會(huì)被啟動(dòng),basic.target之后將控制權(quán)交給sysinit.target.
6.?"sysinit.target"會(huì)啟動(dòng)重要的系統(tǒng)服務(wù)例如系統(tǒng)掛載,內(nèi)存交換空間和設(shè)備,內(nèi)核補(bǔ)充選項(xiàng)等等。sysinit.target在啟動(dòng)過(guò)程中會(huì)傳遞給local-fs.target。這個(gè)target單元的內(nèi)容如下面截圖里所展示。
7.?local-fs.target,這個(gè)target單元不會(huì)啟動(dòng)用戶相關(guān)的服務(wù),它只處理底層核心服務(wù)。這個(gè)target會(huì)根據(jù)/etc/fstab和/etc/inittab來(lái)執(zhí)行相關(guān)操作。
系統(tǒng)引導(dǎo)性能分析
Systemd提供了工具用于識(shí)別和定位引導(dǎo)相關(guān)的問(wèn)題或性能影響。Systemd-analyze是一個(gè)內(nèi)建的命令,可以用來(lái)檢測(cè)引導(dǎo)過(guò)程。你可以找出在啟動(dòng)過(guò)程中出錯(cuò)的單元,然后跟蹤并改正引導(dǎo)組件的問(wèn)題。在下面列出一些常用的systemd-analyze命令。
systemd-analyze time?用于顯示內(nèi)核和普通用戶空間啟動(dòng)時(shí)所花的時(shí)間。
$ systemd-analyze time
Startup?finished?in1440ms(kernel)+3444ms(userspace)
systemd-analyze blame?會(huì)列出所有正在運(yùn)行的單元,按從初始化開(kāi)始到當(dāng)前所花的時(shí)間排序,通過(guò)這種方式你就知道哪些服務(wù)在引導(dǎo)過(guò)程中要花較長(zhǎng)時(shí)間來(lái)啟動(dòng)。
$ systemd-analyze blame
2001ms?mysqld.service
234ms?httpd.service
191ms?vmms.service
systemd-analyze verify?顯示在所有系統(tǒng)單元中是否有語(yǔ)法錯(cuò)誤。
systemd-analyze plot?可以用來(lái)把整個(gè)引導(dǎo)過(guò)程寫入一個(gè)SVG格式文件里。整個(gè)引導(dǎo)過(guò)程非常長(zhǎng)不方便閱讀,所以通過(guò)這個(gè)命令我們可以把輸出寫入一個(gè)文件,之后再查看和分析。下面這個(gè)命令就是做這個(gè)。
systemd-analyze plot?>?boot.svg
Systemd的爭(zhēng)議
Systemd并沒(méi)有幸運(yùn)地獲得所有人的青睞,一些專家和管理員對(duì)于它的工作方式和開(kāi)發(fā)有不同意見(jiàn)。根據(jù)對(duì)于Systemd的批評(píng),它不是“類Unix”方式因?yàn)樗囍鎿Q一些系統(tǒng)服務(wù)。一些專家也不喜歡使用二進(jìn)制配置文件的想法。據(jù)說(shuō)編輯systemd配置非常困難而且沒(méi)有一個(gè)可用的圖形工具。
如何在Ubuntu?14.04和12.04上測(cè)試Systemd
本來(lái),Ubuntu決定從Ubuntu 16.04 LTS開(kāi)始使用Systemd來(lái)替換當(dāng)前的引導(dǎo)過(guò)程。Ubuntu 16.04預(yù)計(jì)在2016年4月發(fā)布,但是考慮到Systemd的流行和需求,剛剛發(fā)布的Ubuntu 15.04采用它作為默認(rèn)引導(dǎo)程序。另外,Ubuntu 14.04 Trusty Tahr和Ubuntu 12.04 Precise Pangolin的用戶可以在他們的機(jī)器上測(cè)試Systemd。測(cè)試過(guò)程并不復(fù)雜,你所要做的只是把相關(guān)的PPA包含到系統(tǒng)中,更新倉(cāng)庫(kù)并升級(jí)系統(tǒng)。
聲明:請(qǐng)注意它仍??處于Ubuntu的測(cè)試和開(kāi)發(fā)階段。升級(jí)測(cè)試包可能會(huì)帶來(lái)一些未知錯(cuò)誤,最壞的情況下有可能損壞你的系統(tǒng)配置。請(qǐng)確保在嘗試升級(jí)前已經(jīng)備份好重要數(shù)據(jù)。
在終端里運(yùn)行下面的命令來(lái)添加PPA到你的Ubuntu系統(tǒng)里:
sudo add-apt-repository ppa:pitti/systemd
你將會(huì)看到警告信息因?yàn)槲覀儑L試使用臨時(shí)/測(cè)試PPA,而它們是不建議用于實(shí)際工作機(jī)器上的。
然后運(yùn)行下面的命令更新APT包管理倉(cāng)庫(kù)。
sudo apt-get?update
運(yùn)行下面的命令升級(jí)系統(tǒng)。
sudo apt-get?dist-upgrade
就這些,你應(yīng)該已經(jīng)可以在你的Ubuntu系統(tǒng)里看到Systemd配置文件了,打開(kāi)/lib/systemd/目錄可以看到這些文件。
好吧,現(xiàn)在讓我們編輯一下grub配置文件指定systemd作為默認(rèn)引導(dǎo)程序??梢允褂肎edit文字編輯器編輯grub配置文件。
sudo gedit?/etc/default/grub
在文件里修改GRUBCMDLINELINUX_DEFAULT項(xiàng),設(shè)定它的參數(shù)為:“init=/lib/systemd/systemd”
就這樣,你的Ubuntu系統(tǒng)已經(jīng)不再使用傳統(tǒng)的引導(dǎo)程序了,改為使用Systemd管理器。重啟你的機(jī)器然后查看systemd引導(dǎo)過(guò)程吧。
結(jié)論
Systemd毫無(wú)疑問(wèn)為改進(jìn)Linux引導(dǎo)過(guò)程前進(jìn)了一大步;它包含了一套漂亮的庫(kù)和守護(hù)進(jìn)程配合工作來(lái)優(yōu)化系統(tǒng)引導(dǎo)和關(guān)閉過(guò)程。許多Linux發(fā)行版正準(zhǔn)備將它作為自己的正式引導(dǎo)程序。在以后的Linux發(fā)行版中,我們將有望看到systemd開(kāi)機(jī)。但是另一方面,為了獲得成功并廣泛應(yīng)用,systemd仍需要認(rèn)真處理批評(píng)意見(jiàn)。
?
評(píng)論