簡介: 近些年隨着軟件系統架構的發展,咱們經歷了從單體應用到分佈式系統,而且逐步向雲原生邁進,而其中微服務架構是最具備表明性,但在微服務設計時又存在各式各樣的問題,但願此文可以幫助你們在微服務架構設計時提供思路和指導。編程
前言&背景
故事開始前先給你們講一個段子,近些年隨着軟件系統架構的發展,咱們經歷了從單體應用到分佈式系統,而且逐步向雲原生邁進,而其中微服務架構是最具備表明性,但在微服務設計時又存在各式各樣的問題,好比微服務拆分粒度過細,服務間調用深度過長,可能就要從新梳理業務考慮進行服務合併,這時就會有人問:「大家爲何把微服務拆了又合?」,你告訴他咱們在「建中臺」;而後隨着業務的快速擴張,資源的利用上hold不住了,又要考慮對系統進行拆解,這時又會有人問:「大家爲何又把微服務合了又拆?」,你告訴他咱們在「拆中臺」;而後,固然還有而後,拆過以後發現有些服務拆的不合理,可能又要進行合併,此時有人問起:「What the hell are you doing ?」,你能夠像一位老者同樣回答他:「天下大勢,分久必合,合久必分。週末七國分爭,併入於秦。及秦滅以後,楚、漢分爭,又併入於漢。漢高祖一統天下,後來光武中興,遂分爲三中臺...」後端

以上相似的場景在實際應用微服務設計時,不少人或許感同身受。如何對微服務進行合理的拆分和設計? 是否有相關的標準和規範能夠參考,答案是有的,不過僅僅是方法論。從哲學的角度上講並不存在普適的方案,不過根據經驗能夠總結和抽象一些方法做爲指導,可是過分抽象以後又很是晦澀難懂,實施起來並非一件容易的事。設計模式
微服務發展簡史
首先咱們先來回顧一下軟件系統架構的發展歷程:單體架構 --> 分佈式/集羣架構 --> 服務化架構(SOA面向服務) --> 微服務架構 --> 網格化/單元化架構安全
總的來講微服務架構囊括了以前架構的全部特色,分佈式集羣部署,面向服務的設計,而微服務更加關注的是服務拆分的粒度,即:一個服務要拆分到多大的維度合適。但隨着系統業務量的增長,服務規模也愈來愈大,相應的也出現了一些新的問題,好比底層系統資源問題、服務間通訊和治理問題、服務總體運維的問題,而SpringCloud、Dubbo等微服務框架只能解決軟件開發層面的問題。早期的微服務,人們關注的重點都是軟件開發層面,近幾年隨着容器化管理技術Docker、容器編排技術Kubernetes等,運維層面技術的成熟和推廣,微服務體系由原來的注重開發,逐漸演變爲設計、開發、運維一體化的DevOps管理模式。網絡

經過服務架構的發展歷程,咱們能夠看出:微服務實現了服務間的解耦,但同時也引起了不少非業務性問題。 好比:服務發現、服務限流、服務監控、服務權限控制、服務版本控制等。Spring Cloud等微服務框架,雖然爲咱們提供了,例如:解決服務發現問題的註冊中心Eurek、解決限流問題的斷路器Hystrix,以及解決服務調用問題的Ribbon、Fegin等技術,可是咱們看看是它如何使用的?導入dependency依賴,將它們和咱們的業務代碼一塊兒打包部署,也就是說Spring Cloud是一種」侵入式」解決方式,它雖然簡化了咱們處理非業務問題的難度,可是開發人員仍是須要對這部分功能必定了解。架構
咱們但願讓業務開發人員,只關心業務代碼開發,而沒必要將精力耗費在非業務代碼的開發上,Service Mesh(服務網格)技術就是這種思想的體現,它能夠幫助將非業務功能從代碼中剝離處理,將整個服務間的網絡通訊抽離下沉到基礎設施層面,例如:服務發現、負載均衡、版本控制、藍綠部署等問題。負載均衡
咱們再回到微服務設計要解決的根本問題,即:微服務如何進行設計和拆分 ,下面梳理了一些在微服務架構設計時經常使用的原則和方法論:框架
- AKF拆分原則
- 業務拆分原則
- 領域驅動設計
- 分層架構設計
AKF拆分原則
咱們先來聊一聊微服務設計的最基本原則:AKF擴展立方體(Scalability Cube)前後端分離

AKF擴展立方體是《架構即將來》一書中提出的可擴展模型,這個立方體有三個軸線,每一個軸線描述擴展性的一個維度。理論上按照這三個擴展模式,能夠將一個單體系統進行無限的擴展。運維
- X軸:指的是水平復制。很好理解,就是將單體系統多運行幾個實例,作個集羣加負載均衡的模式。爲了更好的支撐這種水平伸縮能力,因此係統最好設計成先後端分離而且無狀態服務。這種擴展能力成本最低,實施也最簡單,適合發展初期,業務複雜度低,增長系統容量就能夠解決大部分問題。
- Y軸:指應用中職責的劃分。這部分就是咱們常說的微服務拆分模式,基於不一樣的業務進行拆分。這種屬於業務上解耦的擴展能力,可使團隊更聚焦,同時解決代碼複雜度的問題,但其中必然會牽扯到底層數據的隔離與傳遞,因此難度係數較大,適合業務複雜,數據量大,團隊規模大的場景。
- Z軸:指根據服務或者數據進行分區,好比按地域進行劃分。這是實現成本最高的一種擴展方式,通常在超大型系統會有相似的需求,好比當一個互聯網系統忽然用戶量激增,單一的集羣模式可能沒法承載,那就須要按照用戶所在的地區進行服務和數據的分區。和傳統意義上的分庫本表或者邏輯上多租戶不同,須要對多個分區進行必定的物理隔離,相似近些年金融行業單元化架構,多數據中心的思路。適用於用戶指數級的快速增加,並能夠按照某種規則進行分區。
在關注AKF三個軸線拆分的同時,還須要思考3S原則,即:Safety(安全)、Scale(規模)、Speed(速度)

業務拆分原則
接下來從系統業務角度切入,談談微服務的拆分和設計原則。
明確微服務拆分,設計原則;以業務需求爲中心、高度自治及持續演進爲目標實現微服務化。

對於跨服務的調用首先是從業務角度考慮,作到高內聚,低耦合,經過拆分的原則儘可能減小這種耦合的發生。

領域驅動設計
領域驅動設計(DDD:Domain-Driven Design),是一套更高級的對軟件系統分析和設計的面向對象建模方法。和傳統以數據驅動設計爲中心的架構有很大區別,領域驅動設計更加關注的是領域模型,那麼何爲領域?直白些講領域其實就是指一塊業務範圍。而領域驅動設計就是將業務與業務之間的關係,以及業務內部的邏輯構建出來。

在領域驅動設計中,首先要作的而且也是最重要的一步,就是達成共識,將團隊中包括技術人員、領域專家、產品經理等對該領域相關的業務知識達成共識,你們可以簡單清晰準確的描述該領域的業務含義和規則,這就是統一語言(Ubiquitous Language)。經過達成這種共識來解決在一些中大型軟件系統中的業務複雜度,是一套行之有效方式。

有了通用語言後,如何將業務模型進行組織和落地,這部分就是模型驅動設計(Model-Driven Design)階段。DDD將這個模型設計過程分爲了兩個階段:
- 戰略設計(Strategic design)
- 戰術設計(Tactical design)
所謂戰略設計,也稱爲高層設計,指將系統拆成不一樣的領域,換句話說:哪些是核心域(核心競爭力),哪些是通用域(非核心共用的,可外採的),哪些是支撐域(非核心特有的,可外包的)。
所謂戰術設計,指如何具體的組織不一樣的業務模型,換句話說:這些模型是什麼角色(實體、值對象)?這些模型之間是什麼關係(聚合、聚合根)?這些模型如何協做和演變(領域事件、領域服務、工廠、倉庫、應用服務)?

而後對領域模型進行界限上下文劃分,並標識出之間的依賴關係,造成相似上圖同樣的領域模型設計,最終再將界限上下文或其中的領域模型映射成微服務。
領域驅動設計這種面向業務的設計方法,與今天的敏捷式開發和微服務架構體系具有自然的契合度。
分層架構設計
最後基於以上的設計原則和方法,咱們再來看看分層架構設計,對於分層設計我想你們應該都會不陌生,但在微服務架構中應該如何進行分層,能夠參考以下中臺建設場景:
聚合域:聚合中臺業務完成業務流程 業務域:提供中臺業務能力接口 通用域:提供數據的原子操做接口

分層架構的好處是可讓服務之間關係更加清晰,同層之間儘可能不要相互調用,也要避免跨層級調用,整個調用鏈的深度也要控制在必定範圍。
結束語
沒有最好的設計模式和架構方案,只有對系統持續的優化和演進,須要找到系統性能的瓶頸點,找到架構設計中腐化的地方,找到確實可行的方法,而後,不斷優化和提高系統的質量,架構的魅力正在於此。
「你寫的每一行代碼都是你的名片,你fix掉的每個bug都算數,這不是編程的技術,這是編程的藝術。」 -- 致敬《飛馳人生》
https://developer.aliyun.com/article/783155?utm_content=g_1000257712
本文爲阿里雲原創內容,未經容許不得轉載。