我為什么不喜歡systemd

如果事事都追求客觀,那么不是虛偽就是愚蠢,且沒有主見。by 我

作為第一個被內核啟動的進程,PID 1 有著無與倫比的特殊地位和重任。

在內核準備就緒后,PID 1進程被內核啟動,這個init system負責啟動其他的守護進程,后臺進程和用戶所需的服務。在如此重要的場合,卻在很長一段時間里用著古老的解決方案:SysVinit。這一用就是近20年。

SysVinit由一堆shell腳本組成,在啟動的時候,一個一個腳本按一定的順序串行的執行。整個過程簡單易于理解卻顯得很笨拙。其一,每個服務都必須等待排在它之前的服務啟動完畢后才能啟動,而這些等待有時是非必需的。其二,腳本由shell寫成,用shell寫是簡單了,但卻帶來解析執行時的耗時增加。其三,這種啟動方式會在開機時就啟動所有的服務,而不管它是不是會被用到。

沒有人反對應當對SysVinit進行改進或尋找替代品,Upstart就是由Ubuntu推動的一次嘗試,因其現代的設計理念而被寄予了厚望。但是,Upstart的表現卻不盡如人意,以至于當systemd開始席卷各大發行版的時候,Ubuntu也最終選擇了采用systemd。事實上,Upstart采用的事件驅動模型啟動方式是一種有點別扭的解決方案,因為不是所有的程序或者服務都能和事件的概念對應上的,大部分的服務只是需要啟動,停止,重啟,重載,僅此而已。

到了2010年,systemd橫空出世,自此一發不可收拾。systemd首先帶來的變化,就是系統啟動速度的大大改觀。

它做到了兩點:1)盡可能的啟動少的服務。2)盡可能的并發啟動。

systemd只會保證啟動一開始就必須的服務,如log服務,D-Bus system等等,而像藍牙,打印機這些,因為不是一開機就會馬上用到的,systemd都會推遲去啟動它們,甚至如果你的其他軟件都沒有用到打印機,打印機這個服務進程就不會被啟動。而動態的啟動服務是現代計算機的需要,尤其對于筆記本而言,如果能支持各種硬件的熱插拔,將是對用戶體驗的一大提升。這兩者事實上是一個概念:只啟動必須的服務,而其他的服務等到可用或要用的時候才啟動。

systemd對并發啟動的支持,概念則是源自于Mac OS的launchd。之所以SysVinit需要串行啟動,是由于各種程序各種服務之間是有依賴關系的,GNOME依賴于D-Bus,則GNOME需要等D-Bus完全啟動后才能啟動,而D-Bus和GNOME均依賴于syslog,則它們都需要等待syslog啟動完成后才能啟動,又如網絡連接服務和nginx服務,也是這種先后關系。SysVinit簡單的對這些服務進行先后排序(事實上這個排序任務需要用戶自己完成),然后依次進行啟動,再次強調這兩個詞:簡單,笨拙。要對此進行改進,就要理解各種服務間具體是如何相互依賴的。

we need to understand what exactly the daemons require from each other, and why their start-up is delayed.

服務/守護進程需要等待它所需要的其他服務/守護進程所提供的socket準備就緒后,才能正常的啟動。

既然如此,我們完全可以在一開始就創建好所有的socket,然后并發的啟動所有的服務。這樣做,將會出現兩個場景:
1)A服務通過socket向B服務發送異步請求,若此時B服務還沒有準備好,這些請求將被存入對應的socket buffer,等到B服務啟動完成后,將消費這些請求,而這個過程對于A服務來說,是透明的。
2)A服務通過socket向B服務發送同步請求,若此時B服務還沒有準備好,這個請求將被阻塞,直到B服務啟動完成為止。而結果也僅是這個進程/線程被阻塞,并不會影響其他的啟動任務。

socket可以這么做,D-Bus更加可以這么做,systemd也正是借(cao)鑒(xi)了launchd的這個設計,將原始的串行啟動變為并發啟動。

以上兩點將linux系統的啟動速度提高了一個等級,兩個詞形容:精巧,高效。

如果故事只到這里,那么一切都會很美好,可systemd卻不想這么簡單。

systemd借鑒Mac OS(在開源社區里這被視為罪惡的閉源軟件的代表)的設計,采用C而不是系統管理員熟練的shell,記錄日志采用二進制文件。這幾個“缺點”常被反對者掛在嘴邊用于口水戰。然而,我認為這幾個都無關緊要,最要命的其實是:it is not the unix way.

Arch Linux在決定采用systemd的時候,在論壇里發過一條回復貼:

these things are not hugely important.
let’s ignore all of those old boring arguments

作為常年的Arch Linux使用者,我不喜歡這樣的回應。因為systemd作為一個init system很不純粹,它接管了太多的服務,破壞了我們一直堅持的原則。PID 1不應該管得這么寬:

systemd-journald:
接管了日志服務,而且日志存儲用的是二進制文件。
.timer:
取代了cron。
systemd-consoled:
取代了內核提供的virtual terminal。
systemd-logind:
管理登陸會話。
systemd-networkd:
網絡服務也由它管。
systemd-timedated:
PID 1想幫你打理時間和時區。
udevd:
被合并進了systemd
systemd-boot:
同樣合并自其他項目,管理你的boot過程。
systemd-resolved:
DNS也由PID 1管了。
systemd-ask-password:
密碼它幫你記。
。。。。。


systemd.png

至于Arch Linux,我選中它作為我學習用的的桌面系統,就是看中它夠KISS (Keep it simple,stupid),一切都是可定制可替換的。可選擇了systemd,意味著用戶的選擇權變少,整個系統幾乎都被systemd接管了,systemd的開發者也說,他們想讓構建基于systemd的linux發行版變得簡單,可不是嘛,我看現在Arch,也就是linux kernel+systemd+pacman了,自己家的東西變少,和其他發行版開始趨同了。這樣,使用Arch和使用其他發行版還有什么不同嗎?(是的,我就是在說逼格)

對于服務器系統來說,啟動速度的提升是一件無關緊要的事,穩定性才是王道,所以systemd進入服務器系統,首先要被考慮的是穩定性而不是啟動速度。可systemd接管了這么多服務,集成到單一的binary中,萬一出個什么事,直接整個系統就掛了,你可是一人之下萬人之上的init system??!systemd的代碼質量一直被人詬病不說,不遵循do one thing and do it well原則,將導致的結果就是,一旦某一子程序出問題了,整個系統就掛了,而且還替換不了。

對于桌面系統來說(目前只有開發人員會用linux作為日常的桌面系統吧?),啟動速度確實帶來了很大的幫助,集成一大堆服務也自有其道理,但是,要不是看中linux的可玩性可定制性,誰會用linux發行版作為日常的桌面系統?使用Arch和使用Mac OS,前者讓人覺得掌控了一切,后者讓人感覺被掌控了一切。如果我追求的是啟動速度這些東西,我直接用Mac OS不就完了嗎干嘛折騰Arch呢?(事實上Arch Linux被我用于學習,Winodws和Mac OS被我用于生活娛樂,而工作用的是Ubuntu)。如果說使用Windows是無奈,Mac OS是因其顏值,那么使用Arch就是信仰:)?,F在是,Arch Linux = linux kernel + systemd + pacman。手動再見。

我想,只有你贊成do one thing and do it well 和 KISS原則是一件需要堅持的事情,才會贊同我的觀點,否則,你會覺得我是個傻叉。

我認為systemd做錯的事情,就是在做好init system該做的事情之后,又做了很多不應該做的事情。甚至,只要systemd將它現在接管的這么多服務抽離出來,變成一個個獨立的互不強制依賴的二進制包,反對的人會少很多,我也會開始喜歡它。也有人早已經這么做了,systemd的反對者們創建了一個分支:uselessd。這個項目將systemd的主服務抽離出來,去掉其他不相關的東西(如systemd-journald,udev等),將其改裝成一個純粹的init程序。這個思路是非常對的,可不幸的是,這個項目已經死了。so sad。

到今天,歷史已經改變不了,自fedora率先采用systemd起,如今各大發行版包括Arch,debian,Ubuntu都已經切換到systemd或正在切換到systemd,只有Geetoo還沒決定好。正如uselessd的發起者所說,發行版的維護者們變得懶惰了,systemd一統天下后維護工作將會變得異常簡單。

The End: 我贊賞systemd的設計,當我使用的發行版決定采用它的時候,它卻帶來了個全家桶:(


原文自謝培陽的博客

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容