面試官:說說操作系統(tǒng)微內(nèi)核和Dubbo微內(nèi)核?
你好,我是 yes。
在之前的文章已經(jīng)提到了 RPC 的核心,想必一個 RPC 通信大致的流程和基本原理已經(jīng)清晰了。
這篇文章借著 Dubbo 來說說微內(nèi)核這種設(shè)計思想,不會扯到 Dubbo 某個具體細(xì)節(jié)實現(xiàn)上,和 Dubbo 強相關(guān)的內(nèi)容會在之后的文章寫到。
所以今天的重點在微內(nèi)核,而這個概念我最早是從操作系統(tǒng)那里得知,不過操作系統(tǒng)的微內(nèi)核和 Dubbo 相關(guān)的微內(nèi)核又不太一樣。
Dubbo 的微內(nèi)核廣義上的微內(nèi)核,而操作系統(tǒng)只是針對內(nèi)核實現(xiàn)。
這么說你肯定不清楚,別急,聽我慢慢道來。
我們先看看操作系統(tǒng)的微內(nèi)核。
操作系統(tǒng)中的微內(nèi)核
在維基百科上搜索微內(nèi)核出現(xiàn)的就是:
在計算機科學(xué)中,微內(nèi)核(英語:Microkernel,μ-kernel),是一種內(nèi)核的設(shè)計架構(gòu),由盡可能精簡的程序所組成,以實現(xiàn)一個操作系統(tǒng)所需要的最基本功能,包括了底層的尋址空間管理、線程管理、與進(jìn)程間通信。
這個詞條歸類在操作系統(tǒng)技術(shù)下,所以這里的微內(nèi)核指的就是操作系統(tǒng)的內(nèi)核設(shè)計,與之對應(yīng)的是宏內(nèi)核架構(gòu)。
Linux 就是宏內(nèi)核架構(gòu)。
操作系統(tǒng)我們都知道它是一個中間層,為我們管理底層的硬件資源,為上層服務(wù)提供接口。
提供進(jìn)程管理、內(nèi)存管理、文件系統(tǒng)、進(jìn)程通信等功能。
像 Linux 這樣的宏內(nèi)核設(shè)計是把這些功能都作為內(nèi)核來實現(xiàn),而微內(nèi)核則僅保留最基礎(chǔ)的功能。
比如就留下進(jìn)程的管理、內(nèi)存管理等,把文件管理等功能剝離出去,變成用戶空間的獨立進(jìn)程來提供服務(wù)。
來看下這個維基百科上的這個圖應(yīng)該就很清晰了。
宏內(nèi)核中的一些功能在微內(nèi)核架構(gòu)上都被獨立到用戶態(tài)中,這樣內(nèi)核代碼量就少了。
代碼少了潛在的 bug 就少,出了問題也更容易排查。
系統(tǒng)也就更加穩(wěn)定,不易奔潰,因為那些服務(wù)從內(nèi)核中移除,在用戶空間運行著,如果出了故障,內(nèi)核重啟這個服務(wù)就好了,不會像之前那樣整個內(nèi)核 GG。
拿顯卡驅(qū)動來說,出問題就藍(lán)屏,這要是微內(nèi)核設(shè)計就可以重啟顯卡驅(qū)動。
聽起來好像微內(nèi)核很好?。坎⒉皇?,接下來就說說微內(nèi)核的缺點。
首先是性能問題。
因為很多功能作為獨立進(jìn)程放到用戶空間運行了,所以宏內(nèi)核時的函數(shù)調(diào)用就變成了進(jìn)程間調(diào)用,涉及進(jìn)程間的通信,還會伴隨著內(nèi)核態(tài)和用戶態(tài)的來回切換,我們知道這種上下文切換時比較耗時的。
這性能的問題就有點大了。
然后微內(nèi)核設(shè)計沒那么簡單,想要靈巧、減少耦合、提高可移植性就需要好好的設(shè)計,按照林納斯的話來說:“如果 GNU 內(nèi)核(微內(nèi)核架構(gòu))早在去年春天完成了,我壓根不會開始我的項目(Lniux)?!?
GNU Hurd 采用微內(nèi)核架構(gòu),設(shè)計過于精巧,研發(fā)速度緩慢,性能長期無法提升。
當(dāng)年林納斯還和 Minix 的作者安德魯,對操作系統(tǒng)的宏內(nèi)核和微內(nèi)核的好壞進(jìn)行了一波網(wǎng)絡(luò)口水戰(zhàn)。
我們來回顧一下那段歷史,挺有意思的。
因為 AT&T 把 Unix 商業(yè)化了,大學(xué)不能免費使用 Unix,身為大學(xué)教授的安德魯為了教學(xué)自己搞了個操作系統(tǒng),即 Minix。
安德魯
當(dāng)時的學(xué)術(shù)風(fēng)潮是微內(nèi)核架構(gòu),把核心功能模塊化,劃分為幾個獨立的進(jìn)程,運行在不同的地址空間提高了代碼的可移植和系統(tǒng)的安全性。
所以 Minix 就是按微內(nèi)核架構(gòu)編寫的,當(dāng)然還有上述提到的 GNU Hurd。
而林納斯那時候讀大學(xué),他祖父送了他一臺 Intel 80386,林納斯也看到了安德魯?shù)慕炭茣?,根?jù)書上的內(nèi)容寫出了 Linux。
林納斯
不過沒有按照微內(nèi)核的設(shè)計,而是跟 Unix 一樣采用了宏內(nèi)核架構(gòu)。
安德魯教授看到了 Linux ,然后在 comp.os.Minix 上批評道:宏內(nèi)核的設(shè)計是有害的。
Linux 內(nèi)核耦合度太高,完全是為了 Intel 80386 而設(shè)計的,處理器架構(gòu)進(jìn)化很快的,操作系統(tǒng)應(yīng)該都具備可移植性。
安德魯還提到:都1991年了還用宏內(nèi)核來設(shè)計操作系統(tǒng),這是一種巨大的退步。
林納斯在一天之后進(jìn)行了反擊,他說 Minix 設(shè)計上有缺陷,從哲學(xué)和美學(xué)角度來看微內(nèi)核確實好,但是你看 GUN Hurd 到現(xiàn)在還沒開發(fā)出來。
然后操作系統(tǒng)本來就依靠硬件的特性,所以內(nèi)核本身不需要過度具備可移植性,應(yīng)用程序的可移植性才重要,Linux 比 Minix 好移植多了。
而且 Linux 本來就是為我自己做的,所以契合 80386,如果要移植到別的平臺,代碼都是開源的(Minix 源碼當(dāng)時得買),想要的人自己做咯。
安德魯也做了一波回應(yīng):Minix 有局限性是因為我是教授,因為大部分學(xué)生都只能在低配的機器上使用,所以系統(tǒng)的硬件需求得足夠低,雖然你 Linux 是免費的,但是需要的硬件貴呀。
其實可以看到,兩者并沒有對宏內(nèi)核和微內(nèi)核的技術(shù)細(xì)節(jié)的進(jìn)行深入探討,而是抓住對方的:你這 Minix 代碼還要收費,你這 Linux 需要的硬件這么貴來進(jìn)行“攻擊”,所以稱之為口水戰(zhàn)。
反正口水戰(zhàn)之后雙方都沒有改變各自的設(shè)計,不過林納斯有引進(jìn)微內(nèi)核的思想來改進(jìn)代碼,也改善了可移植性。
微內(nèi)核市面上設(shè)計成功的有 QNX,黑莓手機就是用這個操作系統(tǒng),車用市場也幾乎都用 QNX 系統(tǒng)。
黑莓手機
這手機很多年前我用過,當(dāng)時覺得有點東西的。
宏內(nèi)核的話就提個 Linux ,足夠了。
兩個架構(gòu)都有成功的產(chǎn)品,所以還是取舍的問題,也沒有誰完全壓著誰。
再具體的就不深入了,今天的主角其實是廣義上的微內(nèi)核。
Dubbo 中的微內(nèi)核
Dubbo 的微內(nèi)核是廣義上的,它的思想是:核心系統(tǒng)+插件。
這個微內(nèi)核說白了就是把不變的功能抽象出來稱為核心,把變動的功能作為插件來擴(kuò)展,符合開閉原則,更容易擴(kuò)展、維護(hù)。
小霸王游戲機大家都應(yīng)該玩過,就長這樣的,它的設(shè)計就可以認(rèn)為是個微內(nèi)核設(shè)計。
機體本身作為核心系統(tǒng),游戲片就是插件。
我們想玩哪個游戲就插哪個游戲片,簡單便捷,不影響機體本身。
假設(shè)不把游戲片抽象成插件式,那是不是就難搞了?換個游戲就成為難題了。
所以微內(nèi)核架構(gòu)的本質(zhì)就是將變化的部分抽象成插件,使得可以快速簡便地滿足各種需求又不影響整體的穩(wěn)定性。
這就是微內(nèi)核架構(gòu)的精髓。
這里再扣個細(xì)節(jié),較個真(就是我個人的一點想法)。
Mark Richards 在 《Software Architecture Patterns》的微內(nèi)核章節(jié)里面提到
The core system of the microkernel architecture pattern traditionally contains only the minimal functionality required to make the system operational.
從字面意義來看,Mark 認(rèn)為核心系統(tǒng)指的是可以獨立運行且提供基本功能的最小模塊。
例如 vscode、idea、chrome 等設(shè)計就符合 Mark 認(rèn)為的核心設(shè)計,核心系統(tǒng)提供基礎(chǔ)必備的功能,可以獨立運行。
像 vscode 核心就是編輯器,沒有插件也可以獨立運行,然后又有豐富的插件,來滿足一些特殊需求,擴(kuò)展核心系統(tǒng)的功能。
這里可能會讓人產(chǎn)生誤導(dǎo),認(rèn)為核心必須是能讓系統(tǒng)運行的最小功能模塊。
我認(rèn)為核心不一定需要獨立運行且提供基礎(chǔ)功能,能讓系統(tǒng)運行的最小組織模塊也是核心。
兩個說法的差別在于:只有核心的話系統(tǒng)能否正常的運行。
vscode 沒有插件照樣能運行,能提供基本功能,而小霸王游戲機沒有游戲片那運行個寂寞,玩?zhèn)€球。
但是小霸王這種難道就不算微內(nèi)核了嘛?
就我個人而言,把變與不變區(qū)分出來,把變化封裝成插件就稱為微內(nèi)核設(shè)計。
像 Dubbo 能支持很多協(xié)議、各種負(fù)載均衡的擴(kuò)展、集群的擴(kuò)展等等,它自身的一些功能也是通過擴(kuò)展點實現(xiàn)的,沒有插件也跑不了。
這樣的內(nèi)核就像膠水,把各個插件結(jié)合起來最終提供服務(wù),沒有插件這個系統(tǒng)就沒什么意義。
所以我認(rèn)為核心系統(tǒng)不一定需要能獨立運行,能讓系統(tǒng)運行的最小組織模塊也是核心。。
因此我覺得 Mark 說的不太準(zhǔn)確,容易產(chǎn)生誤導(dǎo)。
當(dāng)然這是文字上面的摳細(xì)節(jié),核心概念都是一致的:抽象出核心,剝離變化為插件。
微內(nèi)核設(shè)計的好處
這里的微內(nèi)核指的是廣義的微內(nèi)核。
作為一個框架或者軟件,擴(kuò)展性非常的重要。
因為一個框架、一個軟件的使用者千千萬,不同的人有不同的需求。
身為框架的維護(hù)者、軟件的開發(fā)者你有精力和能力滿足所有用戶的需求?
做夢,不存在的。
有些 idea 你想都想不到。
比如我之前看到的 vscode 里面有個「坤坤鼓勵師」插件,默認(rèn)你代碼寫一小時之后蔡徐坤來給你跳雞你太美,讓你休息休息......
來感受一下?
所以做一個框架或者軟件,想要讓更多人使用,不僅自身提供的功能要全、性能要好、使用要簡單,讓用戶 DIY,做各種定制化也非常的關(guān)鍵!
Dubbo 的成功其實就離不開它的微內(nèi)核設(shè)計,定制化開發(fā)在很多場景都要用到,畢竟都得稍加改造一番來滿足自己公司的一些特殊需求。
當(dāng)然也不是什么都要微內(nèi)核
微內(nèi)核看起來是很方便,但是設(shè)計起來就不方便了。
需要精心的設(shè)計,抽象出各種擴(kuò)展點。
除了本身的功能還需要管理插件的生命周期、插件如何連接、如何通信等。
有些還需要做沙箱隔離,防止插件污染整個系統(tǒng)等等,本來的內(nèi)部函數(shù)調(diào)用變成了插件間的通信,反正設(shè)計起來是復(fù)雜了。
一般微內(nèi)核適合用在框架的設(shè)計上,或者一些規(guī)則引擎的設(shè)計,只有復(fù)雜的會有很多變化的需求場景才需要用到微內(nèi)核。
像一般簡單的項目,本來就一條直道走到底的那種就算了,不要瞎操作,等下秀折了腿。
最后
微內(nèi)核其實就是一種架構(gòu)思想,可以是框架層面的,也可以細(xì)化到某個模塊的設(shè)計。
歸根結(jié)底就是把變化封裝成插件,可插拔,擁抱變化。
當(dāng)然今天也提到了操作系統(tǒng)的微內(nèi)核,這個和廣義上的微內(nèi)核還是不太一樣的。
巨人的肩膀
https://en.wikipedia.org/wiki/Microkernel
https://en.wikipedia.org/wiki/Tanenbaum%E2%80%93Torvalds_debate
《Software Architecture Patterns》
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!