|
關(guān)于“什么是微服務(wù)”的問題,其實(shí)并沒有一個(gè)統(tǒng)一的認(rèn)識(shí)。這些年在不同的場(chǎng)合里和不同背景的朋友都在探討微服務(wù)。但聊得越多,越發(fā)現(xiàn)大家聊的不是同一回事。和 DevOps 一樣,“微服務(wù)”也是一個(gè)內(nèi)涵十分廣泛的詞。本文從“Microservice“這個(gè)概念的源頭出發(fā),總結(jié)了 4 個(gè)常用的微服務(wù)定義。 James Lewis 原始版的微服務(wù) 6 大特征 這個(gè)版本起源于2012年,這里首先要注意年份,那時(shí)候還沒有 Docker,而且 Netflix 的微服務(wù)化過程也在這個(gè)概念提出之前——2008年就開始了,那時(shí)候甚至連 DevOps 還沒發(fā)明出來。James Lewis 在波蘭第 33 次 Degree in Kraków 會(huì)議上分享了一個(gè)案例,名稱是 “Micro Services - Java, the Unix Way”。在這個(gè)分享里, James Lewis 分享了在 2011 年中參與的一個(gè)項(xiàng)目中所采用的一系列實(shí)踐,以 UNIX 的哲學(xué)重新看待企業(yè)級(jí) Java 應(yīng)用程序,并且把其中的一部分稱之為“ Micro-Services ”。 這個(gè)時(shí)候的微服務(wù)所用的單詞和我們現(xiàn)在所用的 Microservices 這個(gè)單詞有所不同。一方面,采用 Micro 作為形容詞,是和 Monolithic 相對(duì),而不是和 Macro 相對(duì)是源于操作系統(tǒng)這門大學(xué)課程。我們知道,現(xiàn)代的操作系統(tǒng)課程都是以 UNIX 作為案例進(jìn)行講解的。而這兩個(gè)單詞來自于“微內(nèi)核”(Micro-Kernel)和“宏內(nèi)核”(Monolithic kernel)的比較。而非常見的“微觀經(jīng)濟(jì)學(xué)”和“宏觀經(jīng)濟(jì)學(xué)”中的 Micro 和 Macro 兩個(gè)相對(duì)應(yīng)的單詞。 另一方面,服務(wù)要以復(fù)數(shù)形式出現(xiàn),表示的是一個(gè)以上。由于漢語里單復(fù)數(shù)是同型的,所以我們?cè)诜g的時(shí)候會(huì)出現(xiàn)問題。因此,“微服務(wù)”在作為架構(gòu)的形式出現(xiàn)的時(shí)候,我們會(huì)用“微服務(wù)架構(gòu)”稱呼。單個(gè)的微服務(wù)從概念上為了和 SOA 以及其它領(lǐng)域的“服務(wù)”有所區(qū)分,會(huì)以“單個(gè)微服務(wù)”以示區(qū)別。而“微服務(wù)”單獨(dú)拿出來是被看作為一系列技術(shù)實(shí)踐的總稱。 在這個(gè)分享里,James Lewis將所實(shí)踐的“微服務(wù)架構(gòu)”總結(jié)為 6 大特征: 1. Small with a single responsibility —— “小到只有單一原則”在這個(gè)特征里,關(guān)于微服務(wù)有多小有兩個(gè)標(biāo)準(zhǔn):第一個(gè)標(biāo)準(zhǔn)是如果一個(gè)類復(fù)雜的超過一個(gè)開發(fā)人員的理解范圍,那么它就太大了,需要被繼續(xù)拆分。第二個(gè)標(biāo)準(zhǔn)是:如果它小到可以隨時(shí)丟棄并重寫,而不是繼續(xù)維護(hù)遺留代碼,那么它就足夠小。這個(gè)標(biāo)準(zhǔn)有個(gè)很重要的原則就是 Rewrite over Maintain,即“重寫勝于維護(hù)”。 2. Containerless and installed as well behaved Unix services —— “去容器化并且作為 Unix Service 安裝”在這個(gè)特征中,James Lewis 提倡采用 Jetty 這樣的工具集成到 Maven 里,可以很方便的調(diào)試或者部署,然后打包成一個(gè)可執(zhí)行的 JAR 包并以 UNIX 守護(hù)進(jìn)程的方式在系統(tǒng)啟動(dòng)時(shí)執(zhí)行。特別是在 AWS 這樣的公有云環(huán)境下,把這樣的應(yīng)用程序和虛擬機(jī)實(shí)例的初始化腳本結(jié)合在一起。使得應(yīng)用程序的生命周期和虛擬機(jī)的生命周期綁定成為一體,由于守護(hù)進(jìn)程在所有 Unix 系統(tǒng)中都是通用的,因此簡(jiǎn)化整體架構(gòu)的開發(fā)和運(yùn)維。 3. Located in different VCS roots ——“分布在不同的版本控制代碼庫里”在這個(gè)特征中,James Lewis 提到了應(yīng)用程序的分離,他認(rèn)為一個(gè)“微服務(wù)”應(yīng)該完全和另外一個(gè)服務(wù)實(shí)現(xiàn)徹底的隔離,這里當(dāng)然是指的從開始的代碼庫就開始隔離了。他同樣也要求開發(fā)人員看到相似性和抽象,并采用單一的領(lǐng)域來指導(dǎo)開發(fā)團(tuán)隊(duì)的開發(fā)。因此接下來他繼續(xù)討論了領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)和康威定律的重要性。他認(rèn)為界限上下文要足夠的清晰,但可以有所重合。如果沒有辦法做到領(lǐng)域之間很清晰,就通過“物理上的手段”——分離不同的團(tuán)隊(duì)來做到這一點(diǎn)。這不可避免的帶來一些公共代碼,但要把這些公共代碼作為“庫”和“基礎(chǔ)設(shè)施即代碼”來對(duì)待,就像你代碼中用到的開源軟件。并搭建一個(gè) nexus 庫來存儲(chǔ)那些二進(jìn)制依賴。 4. Provisioned automatically ——“自動(dòng)初始化”自動(dòng)初始化的要點(diǎn)不在于如何自動(dòng)化,因?yàn)椴煌膽?yīng)用不同的平臺(tái)有不同的初始化方式。這里的重點(diǎn)在于管理分布式應(yīng)用的復(fù)雜性。所以對(duì)于每個(gè)服務(wù),能夠采用聲明出這些初始化。例如:服務(wù) A,需要一個(gè) 負(fù)載均衡,并且可以自動(dòng)擴(kuò)展。服務(wù) B,也是同樣的聲明方式。而這些聲明可以用基礎(chǔ)設(shè)施即代碼技術(shù)很好的管理起來。 5. Status aware and auto-scaling ——“關(guān)注狀態(tài)和自動(dòng)擴(kuò)展”在這里,他認(rèn)為這些應(yīng)用應(yīng)該是能夠感知吞吐量的監(jiān)控指標(biāo)來自我進(jìn)行擴(kuò)展的。對(duì)于一個(gè)現(xiàn)代的應(yīng)用而言,這是一個(gè)基本的架構(gòu)性要求,但這需要團(tuán)隊(duì)有一定的 DevOps 能力。因?yàn)檫@不光要求開發(fā)人員能夠讓應(yīng)用無狀態(tài)化,而且要求基礎(chǔ)設(shè)施可以及時(shí)捕獲環(huán)境的變化。 6. They interact via the uniform interface —— “它們通過統(tǒng)一格式的接口進(jìn)行交互”在這里,James 建議大家采用已經(jīng)成熟的 HTTP 協(xié)議以及標(biāo)準(zhǔn)的媒體類型進(jìn)行接口交互,而不是采用其它的方式。并且采用 HEATOS 的方式構(gòu)建 Restful API,使其成為一個(gè)超媒體的應(yīng)用狀態(tài)引擎。這樣就可以將狀態(tài)和執(zhí)行過程隔離區(qū)分開來,更加容易進(jìn)行水平擴(kuò)展。此外,它也構(gòu)建了一個(gè)避免架構(gòu)孵化的層,可以獨(dú)立于客戶端持續(xù)演進(jìn)。 在總結(jié)的時(shí)候,它特意提到了 UNIX 哲學(xué)。這引用自Doug McIlroy 的一篇采訪:
從這段話里,我們看到了“微服務(wù)架構(gòu)”和 UNIX 哲學(xué)之間的關(guān)聯(lián):
最后,James Lewis 把上述六點(diǎn)特征變成了一個(gè)六邊形的業(yè)務(wù)能力:
翻譯過來就是:
Martin Fowler & James Lewis 合作版的微服務(wù) 9 大特征 由于在 James Lewis 之后,有很多不同的項(xiàng)目也采用“微服務(wù)”作為它們的實(shí)踐名稱。然而,不同項(xiàng)目之間還是存在一些差異的,且每個(gè)人都按照自己的方式在實(shí)踐“微服務(wù)”。因此,基于“求同存異”的原則,Jame Lewis 的同事 —— 大名鼎鼎的 Martin Fowler 采用一種歸納的方式來解決這個(gè)問題:他認(rèn)為“定義”是一些“共有的特征”(Common characteristics)。Martin Fowler 繼續(xù)采用了 James Lewis 對(duì)這一系列實(shí)踐的命名,并且做了修改,使之成為一個(gè)單獨(dú)的名詞 —— Microservices。 所以,他將微服務(wù)總結(jié)為以下9大特征:
這 9 大特征的中文版具體內(nèi)容請(qǐng)參考這里,限于篇幅原因,本文不展開討論。 我們可以從中看出,Martin Fowler 試圖將 James Lewis 的微服務(wù)定義進(jìn)行一般化推廣,使其不光可以在不同的語言架構(gòu)和技術(shù)棧上使用。又可以兼顧敏捷、DevOps 等其它技術(shù),成為一個(gè)架構(gòu)的“最佳實(shí)踐”集合。但這樣一組實(shí)踐本質(zhì)上并沒有太多的創(chuàng)新,只是把我們本身知道的很多架構(gòu)和設(shè)計(jì)的原則結(jié)合在當(dāng)前的技術(shù)棧上進(jìn)行了一次整體的組合和應(yīng)用。 恰逢一系列互聯(lián)網(wǎng)公司的成功事跡帶來的新實(shí)踐(持續(xù)交付、DevOps)和新技術(shù)(Docker)在經(jīng)歷了早期實(shí)踐者(Early Adopter)實(shí)踐積累后的結(jié)果井噴后。這樣的最佳實(shí)踐的集中反應(yīng)固然得到了技術(shù)人員的掌聲。然而,這種定義對(duì)于妄圖采用“微服務(wù)架構(gòu)“的人來說是一個(gè)很高的門檻。如果這樣的 9 個(gè)特征的總結(jié)是對(duì)”微服務(wù)架構(gòu)“的定義。那么,為了要滿足以上的 9 個(gè)定義,則需要花費(fèi)很大的精力來進(jìn)行改造,而且已經(jīng)超出了技術(shù)升級(jí)和企業(yè) IT 部門的職責(zé)范圍。此外,即便我們知道其中每個(gè)特征所帶來的收益,但卻很難拿出案例和數(shù)據(jù)去佐證滿足這 9 個(gè)特征的改造收益。 避開這 9 個(gè)特征的概念正交性不談,即便這 9 個(gè)特征可以從既有的結(jié)果來回答”什么(What)是微服務(wù)“,但卻沒有給出“為什么(Why)要滿足這些特征”和”如何(How)同時(shí)滿足這些特征”。 如果自己挖的坑填不了,就教給別人來填吧: Sam Newman 版微服務(wù)的兩大特征和 7 個(gè)原則 同樣作為 Martin Fowler 的同事,Sam Newman 在其著作 “Building Microservice”(中文譯名為“微服務(wù)設(shè)計(jì)”)的第一章就重新回答了”什么是微服務(wù)架構(gòu)“并回答了”為什么要采用微服務(wù)架構(gòu)“的問題。 Sam Newman 在書中是這么定義微服務(wù)的(《微服務(wù)設(shè)計(jì)》的翻譯):
Sam Newman 自述的微服務(wù)的定義更加簡(jiǎn)單,包含了兩個(gè)特征:“小” 和 “自治”。 除了繼承 James Lewis 關(guān)于微服務(wù)應(yīng)該有多小的描述以外(當(dāng)然,大小都是基于個(gè)人的主觀判斷),還創(chuàng)造性的用康威定律來約束微服務(wù)的大小,即“能否和團(tuán)隊(duì)結(jié)構(gòu)相匹配”:如果你的團(tuán)隊(duì)維護(hù)單個(gè)服務(wù)很吃力,需要保持團(tuán)隊(duì)大小不變的情況下還對(duì)維護(hù)工作游刃有余,那么這個(gè)服務(wù)就需要繼續(xù)被拆分。 而“自治” 則很謹(jǐn)慎的把 Martin Fowler 微服務(wù)定義的 9 大特征中的“去中心化”、“獨(dú)立” 、”松散耦合“等字眼進(jìn)行了統(tǒng)一。并進(jìn)一步解釋到“一個(gè)微服務(wù)就是一個(gè)獨(dú)立的實(shí)體”。并且從外部,也就是黑盒的角度來看每個(gè)符合'自治'的單個(gè)微服務(wù)所具有的特征,即:
此外,他還采用了更簡(jiǎn)單的“黃金法則”來判斷期'自治性'。即能否修改一個(gè)服務(wù)并對(duì)其部署,且不影響其他任何服務(wù)。如果答案是否定的,說明你的微服務(wù)還不夠”自治“。 從 Sam Newman 的定義中,我們可以推導(dǎo)出“微服務(wù)”的幾個(gè)基本事實(shí):
簡(jiǎn)而言之,以上的兩個(gè)特征的表述主要是將微服務(wù)從邏輯架構(gòu)上和部署架構(gòu)上都看作是一個(gè)正交的原子功能單元。而要做到這一點(diǎn),則需要而要把整個(gè)應(yīng)用系統(tǒng)正確的建模到這個(gè)層次,則需要參考很多的內(nèi)部外部因素。 此外,為了達(dá)到“小”和“自治”的目的,Sam Newman 還總結(jié)了 7 條原則用來在實(shí)施的時(shí)候和具體實(shí)踐結(jié)合,分別是:
可以看出,Sam Newman 把 Martin Fowler 的 9 大特征用更加具體的術(shù)語來重新描述,并且從邏輯上處理了 Martin Fowler 微服務(wù) 9 大特征中概念重復(fù)和不明確的部分,使其更簡(jiǎn)單和明確并且更加可操作。例如把“去中心化的數(shù)據(jù)管理” 和 '去中心化治理'合并為“讓一切都去中心化”等。 更重要的是,Sam Newman 提出了采用微服務(wù)技術(shù)的主要好處,告訴了我們“為什么要用微服務(wù)”:
Chris Richardson 的“微服務(wù)架構(gòu)模式” 2017 年,Chris Richardson 使用 Microservices.io 域名開始推廣自己的微服務(wù)理念。他是這樣定義微服務(wù)的:
中文翻譯過來,大意如下:
在 Chris Richardson 采用了較為簡(jiǎn)單的架構(gòu)定義和準(zhǔn)確的目標(biāo)定義相結(jié)合的方式來定義”微服務(wù)架構(gòu)“:它一方面簡(jiǎn)單的把微服務(wù)架構(gòu)定義成一個(gè)實(shí)現(xiàn)業(yè)務(wù)功能的松散耦合的服務(wù)集合,另一方面又以十分具體的目標(biāo)和結(jié)果(持續(xù)交付/持續(xù)集成)來約束這樣一個(gè)松散耦合系統(tǒng)的效果:組織可以演進(jìn)自己的技術(shù)棧。 Chris Richardson 將“單體架構(gòu)”和“微服務(wù)架構(gòu)”看做兩種架構(gòu)模式。并且在同樣的上下文中對(duì)二者各自的優(yōu)劣進(jìn)行了比較。更加重要的是,Chris Richardson 采用 AFK 擴(kuò)展立方來拆分微服務(wù)從而回答了“如何做微服務(wù)”的問題。 值得注意的是,Chris Richardson 所采用的例子雖然在同樣的上下文中,但由于特征不同并不具備可比較性。因此,他采用了在“單體架構(gòu)模式”(Pattern: Monolithic Architecture)的基礎(chǔ)上描述其局限性的方法引出了“微服務(wù)架構(gòu)模式”(Pattern: Microservice Architecture)。嚴(yán)格的說,Chris Richardson 的“單體架構(gòu)模式”是一種對(duì)現(xiàn)狀的和舉例,并沒有給出其特征和方法的描述,因此不能稱之為模式。而“微服務(wù)架構(gòu)模式”則又是一系列模式的總和,如下圖所示: (點(diǎn)擊查看大圖) 從這個(gè)角度看,Chris Richardson 的這些模式并沒有突破 Sam Newman 在《微服務(wù)設(shè)計(jì)》中總結(jié)出的實(shí)踐。但相較于我們所知道的微服務(wù)的優(yōu)點(diǎn)。Chris Richardson 也列出了微服務(wù)的缺點(diǎn):
相較于之前的微服務(wù)定義而言, Chris Richardson 的微服務(wù)體系比較完整,而不僅僅是總結(jié)和列舉實(shí)踐。Chris Richardson 的'微服務(wù)架構(gòu)模式'不光回答了“什么是(What)微服務(wù)”,也回答了“為什么(Why)要用微服務(wù)”,“什么時(shí)候(When)用微服務(wù)”,“什么場(chǎng)景(Where)下”以及“如何(How)實(shí)現(xiàn)微服務(wù)”的問題。 Chris Richardson 還編寫了一套微服務(wù)的指南,可以在這里查看。 比“什么是微服務(wù)”更重要的事 本文總結(jié)了微服務(wù)常見的 4 個(gè)定義。但比這些定義更重要的是你為什么要用微服務(wù)?你想從微服務(wù)中獲得什么益處?你是否了解為了追求這些益處所帶來的代價(jià)?如果不先明確這些問題,在不理解微服務(wù)架構(gòu)或者技術(shù)所帶來的的風(fēng)險(xiǎn)和成本。盲目的采用所謂的微服務(wù),可能帶來的結(jié)果并不理想。 不過,在討論這些問題之前,坐下來統(tǒng)一一下對(duì)微服務(wù)的理解,會(huì)提升我們討論和實(shí)踐微服務(wù)的效率。 |
|
|