
《微服務(wù)設(shè)計》由 ThoughtWorks 的技術(shù)專家 Sam Newman 編寫,整書 200 多頁,從 “是什么”,“為什么”,“怎么樣”闡述了如何正確的在業(yè)務(wù)中落地微服務(wù)。雖然微服務(wù)是如今很火的一個概念,但是并不是所有場景都適合落地微服務(wù)。書中是這樣定義微服務(wù)的——微服務(wù)就是一些協(xié)同的小而自治的服務(wù),所謂的小而自治就是指當(dāng)修改一個服務(wù)并對其進(jìn)行部署的時候不會影響其他的服務(wù)。使用微服務(wù)的架構(gòu)構(gòu)建產(chǎn)品由很多好處如:服務(wù)間技術(shù)的異構(gòu)性、服務(wù)之間的彈性、能對單個服務(wù)進(jìn)行擴展、簡化部署及快速回滾、讓服務(wù)和組織架構(gòu)相匹配。但這些好處并不是一蹴而就的,而是需要將微服務(wù)所需的基礎(chǔ)設(shè)施搭建好后才能享受到使用微服務(wù)的這些好處。
微服務(wù)不是所有情況都適用,當(dāng)你接手一個全新的項目而你對這個項目所涉及到的業(yè)務(wù)領(lǐng)域不熟悉,不能快速正確的劃分服務(wù)領(lǐng)域界限的時候就不適合套用微服務(wù)的開發(fā)框架。這時候應(yīng)該將整個項目開發(fā)完成再在維護(hù)過程中熟悉各個領(lǐng)域的分界,進(jìn)行上下文的分割,到了需要用上微服務(wù)的彈性優(yōu)勢的時候再進(jìn)行劃分。
為了將整個業(yè)務(wù)線往微服務(wù)調(diào)整需要由上而下的調(diào)整,這是就需要一個演進(jìn)式架構(gòu)師。如果將軟件系統(tǒng)的構(gòu)建比作建筑,那么演進(jìn)式架構(gòu)師所擔(dān)任的角色就是城市的規(guī)劃者,不需要對軟件開發(fā)的各個方面進(jìn)行控制,但必須要保證開發(fā)人員能夠在其搭建的框架上舒適地進(jìn)行開發(fā)——這也是演進(jìn)式架構(gòu)師的一個重要職責(zé)。演進(jìn)式架構(gòu)師在團(tuán)隊建設(shè)中需要發(fā)揮其重要的作用,首先需要制定一個系統(tǒng)級的讓團(tuán)隊成員信服的技術(shù)愿景,然后根據(jù)這個技術(shù)愿景制定出相應(yīng)的技術(shù)原則,然后通過團(tuán)隊溝通不斷地將工作流程和工作成果往這個技術(shù)原則上靠。演進(jìn)式架構(gòu)師理解成功要靠不斷的取舍,不可能一套方法永遠(yuǎn)適用。
當(dāng)有了落地微服務(wù)的決心和有了團(tuán)隊的演進(jìn)式架構(gòu)師,就開始對原有的服務(wù)進(jìn)行改進(jìn)和構(gòu)建使用于微服務(wù)架構(gòu)的基礎(chǔ)設(shè)施。設(shè)計微服務(wù)、構(gòu)建微服務(wù)基礎(chǔ)設(shè)施,這兩個主題是整本書的重要部分。
微服務(wù)設(shè)計原則

其中“高度可觀察”、“自動化的文化”、“獨立部署”這幾個原則將在下面的微服務(wù)基礎(chǔ)設(shè)施中詳細(xì)介紹。
圍繞業(yè)務(wù)概念建模原則就是說劃分服務(wù)時應(yīng)該以業(yè)務(wù)為標(biāo)準(zhǔn),而不是以技術(shù)概念為標(biāo)準(zhǔn)。當(dāng)服務(wù)以業(yè)務(wù)劃分的時候,組織上的劃分也應(yīng)該以業(yè)務(wù)為標(biāo)準(zhǔn)。按照康威定律——任何組織在設(shè)計一套系統(tǒng)時,所交付的設(shè)計方案在結(jié)構(gòu)上都與該組織的溝通結(jié)構(gòu)保持一致,也就是說人員的配置不以所處的崗位來集中辦公,而是以功能小組的形式集中辦公。這也有一個問題就是,公司職工的崗位保持恒定的情況下,當(dāng)一個服務(wù)完成迭代進(jìn)入維護(hù)狀態(tài),原小組可能會重新打散編排,這時候原服務(wù)應(yīng)該怎么進(jìn)行維護(hù)。這就牽涉到另外一個概念稱為內(nèi)部開源。原小組解散前可以將服務(wù)代碼進(jìn)行內(nèi)部開源,推選幾個核心成員作為開源項目的維護(hù)人,以維護(hù)開源項目的方式繼續(xù)維護(hù)原有的服務(wù),這樣能避免人員流動帶來的維護(hù)困難。
隱藏內(nèi)部實現(xiàn)細(xì)節(jié)原則很好理解,從編程的角度來,單個部件要求高內(nèi)聚,部件之間低耦合是最好的情況。既然使用了微服務(wù)架構(gòu),那么單個服務(wù)高內(nèi)聚,服務(wù)之間低耦合也就是基本的要求。當(dāng)拆解單塊應(yīng)用時,最大的耦合就是原有的數(shù)據(jù)庫,如使用外鍵關(guān)系來控制一致性。
一切去中心化原則,這里的去中心化指的是技術(shù)選型的去中心化和團(tuán)隊的去中心化。團(tuán)隊去中心化就是給予業(yè)務(wù)團(tuán)隊足夠的決策和控制權(quán),讓其能夠獲取到更多的資源簡化開發(fā)和測試的流程。技術(shù)選型的去中心化就是服務(wù)間調(diào)用使用協(xié)同的方式而不是使用編排的方式。所謂編排的方式就是一個事務(wù)造成的上游調(diào)用,由一個組件依次執(zhí)行。例如,一個訂單系統(tǒng),當(dāng)發(fā)生一起訂單的時候會依次調(diào)用訂單系統(tǒng)的增加訂單、倉庫系統(tǒng)的庫存查詢、庫存系統(tǒng)的庫存減量、通知系統(tǒng)發(fā)送通知等,由于是依次執(zhí)行的,發(fā)起調(diào)用的組件就成了這次調(diào)用的中心,編排接下來調(diào)用的順序。而協(xié)同的方式則是通過異步事件來完成。還是一個訂單系統(tǒng),當(dāng)發(fā)生一起訂單的時候,當(dāng)前組件會生成一個事件,訂單系統(tǒng)、倉庫系統(tǒng)、通知系統(tǒng)等都會訂閱這個事件,然后收到這個事件后觸發(fā)增加訂單、庫存查詢、庫存見諒、發(fā)送通知等操作。
隔離失敗原則,當(dāng)微服務(wù)達(dá)到一定規(guī)模后,故障就難以避免,如何處理故障就成了微服務(wù)架構(gòu)中重要的一環(huán)。有一些組織會使用流程和控制來試圖組織故障的發(fā)生,但更好的方法時假設(shè)一切都會失敗,然后從不同的角度去思考如何解決問題。在分布式系統(tǒng)中處理延遲比處理失敗困難的多,當(dāng)一個下游服務(wù)向上游服務(wù)發(fā)送請求時,由于某種原因上游服務(wù)已經(jīng)失敗,但 http 連接的設(shè)置問題導(dǎo)致下游服務(wù)一直在等待,這時會導(dǎo)致調(diào)用該下游服務(wù)的服務(wù)也處于等待。為了處理這個問題,在處理服務(wù)間請求的時候應(yīng)該正確地設(shè)置超時,然后實現(xiàn)一個斷路器,第一時間避免給一個不健康的服務(wù)發(fā)送調(diào)用。所謂的斷路器,會記錄請求成功與否,當(dāng)積累到一定數(shù)量的失敗后會打開斷路器,當(dāng)請求處于斷路狀態(tài),就會快速的失敗,等待一定時間后再重試請求,如果得到了正常的響應(yīng)就會重置斷路器。
微服務(wù)基礎(chǔ)設(shè)施
微服務(wù)的基礎(chǔ)設(shè)施就是微服務(wù)設(shè)計原則中的“自動化的文化”、“獨立部署”、“高度可觀察”的實現(xiàn),微服務(wù)的基礎(chǔ)設(shè)施主要包括微服務(wù)部署,測試,線上監(jiān)控時用到的一系列設(shè)施。在我接觸的一些開發(fā)人員并不關(guān)注部署、測試和線上監(jiān)控感覺這是運維和 QA 的責(zé)任,實際上并不是這樣的,部署、測試和監(jiān)控是微服務(wù)實踐中極為重要的部分。
先說部署,微服務(wù)的部署中會使用持續(xù)集成的技術(shù),持續(xù)集成能保證新提交的代碼和已有代碼進(jìn)行集成。持續(xù)集成推薦每天都簽入代碼到主線,避免修改堆積導(dǎo)致后來的的集成變得困難;還推薦維持一組測試來驗證修改,包括驗證語法,檢測修改是否破壞了系統(tǒng)的原有行為;最后使用持續(xù)集成的模式的話需要把修復(fù) CI 錯誤當(dāng)作第一優(yōu)先級處理。以上面的原則為基礎(chǔ)打造的一套部署流程就是我們所說的構(gòu)建流水線。當(dāng)一個修改經(jīng)過一個構(gòu)建流水線會得到一個構(gòu)建產(chǎn)物,這個構(gòu)建產(chǎn)物可以是 Ruby 的 Gem,Java 的 Jar, .net 的 dll 等,構(gòu)建產(chǎn)物將直接部署到生產(chǎn)環(huán)境中運行。
應(yīng)用的部署會涉及到服務(wù)器的配置與修改,一個良好的實踐事應(yīng)該禁止對任何的生產(chǎn)服務(wù)器進(jìn)行手動的配置和修改,那么問題來了怎么修改生產(chǎn)服務(wù)器呢?生產(chǎn)服務(wù)器可以看作是由一個特定的構(gòu)建流水線構(gòu)建出來的產(chǎn)物,構(gòu)建的結(jié)果就是一個系統(tǒng)鏡像,當(dāng)使用這個系統(tǒng)鏡像創(chuàng)建一個服務(wù)器時,修改就生效了。但使用這種方法應(yīng)該注意磁盤數(shù)據(jù)的保存,使用云服務(wù)廠商提供的云磁盤的時候可以將業(yè)務(wù)和數(shù)據(jù)分別存放在兩個不同的虛擬磁盤,構(gòu)建只影響業(yè)務(wù)磁盤,數(shù)據(jù)磁盤在構(gòu)建完成后掛載。構(gòu)建系統(tǒng)環(huán)境和構(gòu)建服務(wù)可以通過觸發(fā)器機制來實現(xiàn)自動化。
接著說的是測試,上面說部署流水線的時候說到使用一組測試來驗證修改后的服務(wù)是否按照預(yù)期工作。在“測試金字塔”模型中把自動化測試分為單元測試、服務(wù)測試和用戶界面測試。單元測試就是在不啟動服務(wù)的情況下測試一個方法或者類是否如預(yù)期運行,單元測試是面向技術(shù)而不是面向業(yè)務(wù)的,能夠在小范圍內(nèi)快速的檢查修改是否導(dǎo)致程序不正確,讓開發(fā)者能夠放心的修改代碼。服務(wù)測試就是面向單個服務(wù)的,通過啟動服務(wù)后測試整個服務(wù)是否正確運行,運行結(jié)果是否符合預(yù)期。到了用戶測試就是覆蓋整個業(yè)務(wù)的測試,到了這一步已經(jīng)是面向業(yè)務(wù)的測試,用于驗證業(yè)務(wù)是否按照產(chǎn)品設(shè)計的方式運行。書中專門討論了端到端測試(也就是用戶測試)在微服務(wù)場景下落地的問題。由于端到端測試涉及的是多個服務(wù)之間的調(diào)用,會出現(xiàn)一些環(huán)境波動,導(dǎo)致端到端測試有時不能通過,有時能通過,這就叫做端到端測試的脆弱性。脆弱的測試可能不是業(yè)務(wù)的編寫和部署問題,當(dāng)出現(xiàn)脆弱的測試時,應(yīng)該第一時間修復(fù)這個測試,如果不能修復(fù)應(yīng)該將其從測試套件中移除,在不受打擾的情況下進(jìn)行修復(fù)。如果不管脆弱的測試,開發(fā)人員將會對測試套件失去耐心。
最后的基礎(chǔ)設(shè)施是監(jiān)控,在服務(wù)部署運行的時候通過監(jiān)控及時發(fā)現(xiàn)錯誤的地方,然后手動或者自動干預(yù),防止一處錯誤造成雪崩。傳統(tǒng)的監(jiān)控包括對服務(wù)器指標(biāo)的監(jiān)控和服務(wù)的監(jiān)控,服務(wù)器指標(biāo)的監(jiān)控就是如 CPU 使用率、內(nèi)存使用率、網(wǎng)卡收發(fā)包等和服務(wù)器有關(guān)的指標(biāo),服務(wù)指標(biāo)的監(jiān)控就是監(jiān)控如響應(yīng)的延時、緩存的命中率等和業(yè)務(wù)服務(wù)質(zhì)量有關(guān)的指標(biāo)。單條監(jiān)控數(shù)據(jù)是沒有意義的,當(dāng)收集足夠多的數(shù)據(jù)然后將其聚合顯示出來,再加以分析,才能得出實時得出的監(jiān)控數(shù)值是否符合統(tǒng)計規(guī)律。在服務(wù)指標(biāo)監(jiān)控方面還可以用到語義監(jiān)控。語義監(jiān)控在處理服務(wù)間交互復(fù)雜時能夠更加準(zhǔn)確的反應(yīng)系統(tǒng)是否正確工作。在實現(xiàn)語義監(jiān)控的時候可以手動創(chuàng)建一個模擬操作來驗證系統(tǒng)是否正確運行,這個過程就像端到端測試一樣,只不過時線上的端到端測試。
微服務(wù)架構(gòu)下監(jiān)控還有了新的挑戰(zhàn),就是服務(wù)之間的交互錯綜復(fù)雜,這時監(jiān)控需要監(jiān)控到整個調(diào)用鏈的健康情況,也需要了解整個調(diào)用鏈的調(diào)用情況,這就引入了關(guān)聯(lián)標(biāo)志監(jiān)控。關(guān)聯(lián)標(biāo)志監(jiān)控就是在觸發(fā)第一個調(diào)用的時候生成一個 GUID,然后將其傳遞給后續(xù)調(diào)用,通過這個 GUID 關(guān)聯(lián)標(biāo)志就能推斷出整個調(diào)用鏈的情況。書中給的建議事盡早的實現(xiàn)關(guān)聯(lián)標(biāo)志監(jiān)控,因為沒有這個工作你將不知道一條調(diào)用鏈的上下游關(guān)系,當(dāng)調(diào)用失敗時也無從考究哪一步調(diào)用發(fā)生了錯誤。
總結(jié)
以上就是我閱讀 《微服務(wù)設(shè)計》一書后的閱讀總結(jié),整書 200 多頁,本篇總結(jié)不可能都涉及到所有的內(nèi)容,只希望能夠幫助大家快速的了解這本書。