糯米文學吧

位置:首頁 > 職業 > 系統架構師

微服務的架構設計

近年來,服務化和微服務的架構隨着線上業務對響應變化和發佈頻率要求的不斷提高已經變得日益常見。下面yjbys小編為大家準備了關於微服務架構設計的文章,歡迎閲讀。

微服務的架構設計

  前言

許多企業對微服務思考的關注點也從最初的“該不該用”、“該如何用”逐漸轉向“如何評價服務拆分的好壞”、“服務拆分後的數據如何治理”這樣更加具體而實際的方面。縱觀社區裏與微服務有關的話題,既有一些適合大眾閲讀的概念入門科普文章,也有一些像“架構去中心化”、“消息異步解耦”、“最終一致性補償”這類專業性的技術討論,但卻很少看到能夠比較深入的介紹微服務實施經驗,説清楚“什麼地方會有什麼坑”這類問題的實踐性內容。

若將微服務的方方面面鋪開,將是一個非常龐大而複雜的知識體系。萬事開頭難,如何邁出服務劃分的第一步是對於那些從未採用過微服務的項目首先要面對的問題。雖然服務的劃分本來是一件十分憑藉架構師個人經驗和對業務理解的主觀工作,但其中仍然有些規律可循。根據服務的類型特點,可以有以下幾種常見的方式:

1. 根據業務進行建模,依據業務領域的邊界劃分,這也是當下微服務社區十分推崇的領域驅動設計(Domain Driven Design,簡稱DDD)方法;

2. 根據資源使用類型劃分,這種方式主要使用在對硬件資源需求很高、或對特定硬件類型/區域地址等存在依賴的大型服務系統,例如系統的某些功能非常消耗CPU、或是某些功能必須在有加密狗設備的機器上運行。此時可以依據系統各部分對不同資源的需要作為邊界進行最安全的劃分,以最大化運行效率;

3. 根據數據邊界劃分,直接從數據表結構或數據源着手,依據數據歸屬關係界定服務。這種劃分方法簡單粗暴且能避免數據耦合,但容易導致潛在隱患,甚至可以被認為是一種反模式。僅僅對於強數據驅動的系統,如某些報表系統和多數據源ETL系統等適用,在實際案例中很少見。

從現實上來説,我們平時遇到的絕大部分系統都是需要為特定終端用户羣體服務的。因此,採用基於業務領域的建模的方法通常都會是個不錯的選擇,它也是目前在劃分服務問題中的最主流的方法。不過即使有了理論指導的支撐,服務劃分裏的利弊權衡並不是非黑即白的事情,依然存在不少模稜兩可之處,只有在犯下一些錯誤後才能摸索出適合自己系統的方法。本文將會聚焦在這些點。

沒有什麼能比一個具體而貼近真實的案例更具有代表性了。因此,我們將剖析一個傳統行業企業的線上業務:某汽車產品代理商的線上銷售和售後平台,介紹它在微服務轉型過程中遇到的種種情況,希望能以此作為前車之鑑,讓後來者避開不必要的趟坑。這個案例中講述的場景原型並非完全來自同一個項目,而是從我們過去一年中所經歷的多個項目的實際場景抽取出來的,去除了其中的敏感信息,並添加了基於真實情況的適當演繹,使之更加完整。簡單介紹一下案例的背景:這是一家頗具規模的汽車代理商企業,承接多個國際一線品牌汽車的銷售和周邊資源整合的業務,具有龐大的實體店網點。其線上的IT業務系統已經存在了十餘年,提供的功能從最初的進銷存管理、客户信息管理等到現在的面向消費者客户的服務系統,十分複雜。系統中的線上銷售和售後平台部分是相對比較新、且需求變化特別迅速的部分,也是目前出問題最頻繁、收到抱怨最多的部分。

  不要從數據庫開始建模

傳統軟件開發中,數據模型被認為是整個系統的核心,業務邏輯僅僅是對數據的CRUD加上簡單的計算呈現。有些項目團隊的架構評審會花很多時間來討論系統龐大的ER圖(實體關係圖)設計。但在微服務架構設計時,ER圖並非最佳選擇,特別是在服務劃分時採用ER圖進行建模甚至是十分有害的。

在領域驅動設計的實踐中,有一個和ER圖建模有些相似的環節,叫做“領域建模”。相比ER圖建模通常只有開發人員參與,並從數據表的角度考慮模型的方法,領域建模的過程需要由產品的業務人員和核心開發人員共同參與,先梳理用户場景,然後從業務領域角度,逐步確定場景中的實體、關聯和聚合等元素。其中的“實體、關聯”與ER圖中的“實體、關係”有些相似,但含義並不一致。領域模型中的“實體”本質上是業務場景中需要被持久化存儲的對象,但存儲方式不一定是數據庫,更不一定是關係型數據庫,而ER圖中的“實體”最終對應的就是關係型數據庫的表。領域模型中的“關聯”是兩個實體在業務上下文之間有業務含義的聯繫,而ER圖中的“關係”只的是兩張表之間的一個關聯外鍵。

  那麼,使用ER圖給微服務建模會存在什麼問題呢?

首先,ER圖設計時假定了使用的是關係型的數據庫。微服務的一個特點在於它支持異構架構,系統的不同部分,依據實際需要可選擇不同的編程語言、框架以及數據庫的類型。關係型數據庫採用平面表的結構,如果有兩類嵌套關係的對象,只能使用關聯表來表達兩個實體之間的關係,然後通過複雜的SQL語句在查詢時將多個表拼成更大的平面表,最後在業務代碼裏再分解到各個獨立的對象裏去。這些單獨的表又可能在其他地方與另一個表存在關聯查詢。這樣設計出來的表結構的宂餘很低,且使用非常靈活,但正是這種靈活性往導致系統中多個業務邏輯表出現錯中纏繞的關係,從而使剝離單獨服務進行異構設計變得困難。

其次,ER圖還會導致實體相似的不同業務邏輯在設計時被耦合在一起。舉一個具體的例子,在汽車代理銷售系統中,不同品牌汽車的購買流程後端實際上分別對接的是完全不同的分銷渠道系統和邏輯流程,但它們在用户視圖上所需要的信息比較一致,因此存儲的數據結構也比較相似。這個系統在最初設計時採用了ER圖的方式建模,由於ER圖模型不關心業務層面上的東西,不同品牌汽車的實體數據看上去都是一種類型的數據,僅僅是一個品牌字段的差異而已,因此被理所當然的設計成了同一張表。上層邏輯實現的時候使用了大量的if-else語句來區分各種品牌的購買流程,結果使得多條完全不同的業務線糅合在同一個上下文裏,後來的開發非常容易在這裏錯改、漏改代碼。若當初使用的是領域建模,則不同的購車流程會自然的被劃分到各種不同的用户場景,即使它們在數據結構上看起來基本相同,也會被識別為兩個獨立的上下文,這就會使得未來劃分服務時能夠更加容易。

最後,ER圖設計的架構會使得系統的模塊之間傾向於使用數據庫集成,而非API集成。在ER圖中沒有明確劃分模塊和表的所有權關係,所有的數據表對所有的模塊都是可見的,倘若不加額外約束,各個模塊便都會輕易的讀寫其中的內容。數據集成並不會直接導致服務無法拆分,但由於數據的所有權不清晰,十分容易引發的意想不到的狀況。還是舉銷售平台的例子,在ER圖建模得到的.模型中,有一張與購買記錄相關的表。在一次銷售業務的代碼更新中,對購買結果的增加了字段,在測試過程中沒有發現問題,結果上線幾天以後,由於售後服務也在修改這個表而導致出現了髒數據,造成難以排查的故障。

當然,我們並非要完全否認ER圖建模的價值,只不過通過數據庫角度建立模型的過程容易傾向於設計出龐大的單體應用,因而不太適應於服務劃分的目的。

  端到端的劃分服務

在拆服務時要端到端的劃分,這是我們在設計微服務時經常聽到的一句話。端到端的劃分,指的是一個服務負責一個業務領域,這個功能領域的所有邏輯、數據都歸它管,這有利於微服務的數據治理。與之相對的是MVC那樣的橫向服務劃分,將所有數據歸一塊,所有邏輯歸另一塊,特別是在跨團隊管理的情況,橫向劃分服務會帶來十分高昂的協調和聯調成本。

道理不必多説,還是講個例子吧。在汽車銷售平台的最初架構中,使用了典型的MVC三層結構,由於人比較多,分成了前台組、後台組,就時不時要出現新開發一個功能,一動底層數據結構,結果上層的另一個不相干頁面掛了,一查發現原來那這個頁面間接的用了同一個數據模型。比較典型的例子是,有一回負責後台的小組調整了汽車銷售服務裏面的汽車參數信息相關的對象結構,結果一上線,銷售功能正常,試駕服務的頁面掛了。原來是試駕功能的前端開發人員在處理汽車信息時候,看到銷售模塊有現成功能,就直接拿來複用了。這便是服務上下層分團隊開發導致的問題。

此外,橫向劃分服務也不利於系統的開發效率的提升。不同業務服務對功能發佈頻率的的需求是不一樣的,比如試駕平台經常推出新的優惠促銷活動,需要儘快進行一次版本更新,於此同時售後服務有一個需要和第三方聯調的功能也已經差不多完成並提交到代碼倉庫了,但由於需要協調第三方系統的時間,最近還不能夠上線,此時兩邊的業務主管就要開掐了。類似這樣的情況其實經常發生,通常使用特性分支、特性開關等流程或者技術手段能夠規避一部分業務開發進度不一致的風險,但若要從根本上解決這種問題,還是需要端到端的按業務來劃分服務。

最後,橫向劃分模塊對於問題的追蹤調試也不友好,幾乎每次事故調查總是要穿插涉及在幾個團隊之間不停的協調開會,因為一個完整業務流總是要貫穿前後幾個層的功能。

需要指出的是,端到端劃分服務並非是説服務與服務之間都是平級的。實際上,服務之間可以再聚合成更高層級的組合服務的,以及在最頂端的API Gateway也可以算是一類服務。只不過,在核心業務層的這些服務,每個都單獨提供了某項特定的業務價值。

  識別核心業務服務

微服務的架構通常並非是一開始就重頭設計出來的,而是先有整塊的單體架構,隨着業務的複雜度上升,才逐步拆分出來。業務領域建模除了能用來指導適當的服務劃分,另一個重要的作用是讓工作聚焦到核心的業務服務中。

無論多複雜系統都是為特定業務價值而存在的。在系統的實現中必然會存在與核心業務最相關的部分、輔助核心業務的部分、和非核心業務關係的部分。它們在領域驅動設計的術語中稱為“核心域”、“支撐子域”和“通用子域”。在進行領域建模的時候就應該順便識別出系統裏的關鍵領域。將系統的業務領域羅列出來然後劃分出重要性,這件事情聽起來似乎是多此一舉,甚至有點荒唐,但對於複雜系統,實際去做這件事帶來的價值可能遠比它看起來更大。

標籤:架構設計 服務