架構的本質是管理複雜性,微服務本身也是架構演化的結果

為應對如今無線優先和全渠道用戶體驗的需求和挑戰,我們該如何設計靈活的面向體驗的微服務架構?它有哪些模式和最佳實踐?攜程,Netflix和SoundCloud這些知名互聯網公司是如何實踐面向體驗的微服務架構的?在過去的2015年,大牛馬丁福勒對微服務有哪些新的觀點?

文末有關於微服務的系統學習路線和架構學習資料,有興趣的可以看看

一、微服務架構原理

微服務是個新概念,但它沒有一個明確的定義,各家對微服務的描述不盡相同,本人更傾向於用一些架構原理來描述它,因為架構原理是相對抽象和穩定的,而具體實現可以千差萬別。微服務原理和軟件工程,面向對象設計中的基本原理相通,體現如下:

  1. 單一職責(Single Responsibility),一個服務應當承擔儘可能單一的職責,服務應基於有界的上下文(bounded context,通常是邊界清晰的業務領域)構建,服務理想應當只有一個變更的理由(類似Robert C. Martin講的:A class should have only one reason to change),當一個服務承擔過多職責,就會產生各種耦合性問題,需要進一步拆分使其儘可能職責單一化。
  2. 關注分離(Separation of Concerns),跨橫切面邏輯,例如日誌分析、監控、限流、安全等等,儘可能與具體的業務邏輯相互分離,讓開發人員能專注於業務邏輯的開發,減輕他們的思考負擔,這個也是
    有界上下文(bounded context)的一個體現。
  3. 模塊化(Modularity)和分而治之(Divide & Conquer),這個是解決複雜性問題的一般性方法,將大問題(如單塊架構)大而化小(模塊化和微服務化),然後分而治之。

微服務架構同時還是一個組織原理的體現,這個原理就是康威定律(Conway’s Law),Melvin Conway在1968年指出:“Any organization that design a system(defined broadly) will produce a design whose structure is a copy of the organization’s communication structure”,翻譯成中文就是:設計系統的組織,其產生的設計和架構等價於組織間的溝通結構。Dan North對此還補充說:“Those system then constrain the options for organization change”,簡言之,這些系統在建成之後反過來還會約束和限制組織的改變。下面兩個圖進一步解釋了這一組織原理:

架構的本質是管理複雜性,微服務本身也是架構演化的結果

團隊結構和系統架構不匹配

一般企業剛起步時,業務規模小,開發團隊規模也小,所以通常開發出來的系統是單塊的;隨著業務的擴大,團隊規模也會隨之擴大,這個時候多團隊組織架構和單塊系統架構之間就會產生不匹配問題(溝通協調成本增加,交付效率低下等等),如果不對單塊架構進行解耦和調整以適應新的團隊溝通結構,就會制約組織生產力和創新速度。

架構的本質是管理複雜性,微服務本身也是架構演化的結果

團隊結構和系統架構匹配

把單塊架構按照業務和團隊邊界進行拆分,重新調整為模塊化分散式架構(微服務架構是一種方案),那麼組織團隊溝通結構和系統架構之間又能匹配起來,各個團隊才能夠獨立自治地演化各自的子系統(微服務),這種架構的解耦和調整可以解放組織生產力和提升創新速度。文末有關於微服務的系統學習路線和架構學習資料,有興趣的可以看看

二、用戶體驗適配層(Backend For Frontend)

眾所周知,隨著無線技術的發展和各種智能設備的興起,互聯網應用已經從單一Web瀏覽器時代演進到以API驅動的無線優先(Mobile First)面向全渠道體驗(omni-channel experience oriented)的時代,如下圖所示:

架構的本質是管理複雜性,微服務本身也是架構演化的結果

從單一網站到API驅動的全渠道體驗

應用架構的新挑戰是:

  1. 用戶接入形式的多樣性,無線(手機、Pad),Web,互聯網電視,第三方合作應用等等,各種用戶設備的屏幕大小,操控體驗方式各不相同,例如,手機設備的屏幕較小,能夠展示的數據量小,交互方式以觸控為主,也可通過條形碼掃描器;
  2. 有些用戶設備的帶寬受限,同時應用的UI一般宿主在客戶端,有些頁面需要組合好幾個後臺業務服務的數據和功能,如果直接在客戶端發起對多個後臺服務的調用,勢必造成大量網絡開銷影響性能,這個有點類似數據庫查詢中的n+1問題。

BFF本質上是一個後端中間層,但是它的作用主要是適配前端不同用戶體驗(無線,桌面,智能終端等等),所以稱為用戶體驗適配層,它的適配作用主要是:

  1. 裁剪和格式化,對後臺的通用數據模型進行適當的裁剪和格式化,以適應不同的用戶體驗展示的需要;
  2. 聚合編排,對後臺服務數據進行編排和預聚合,這樣可以有效簡化客戶端邏輯和減少網絡調用開銷。

下圖展示了一個無線BFF:

架構的本質是管理複雜性,微服務本身也是架構演化的結果

Sam推薦理想情況下針對每種用戶體驗類型需要一個BFF(one BFF per user experience),例如Mobile BFF,Desktop BFF,這可以做到職責單一和關注分離(遵循有界上下文原則),但是BFF過多也會造成

代碼邏輯重複冗餘的問題,需要權衡。UI和BFF理想是同一個團隊負責,這樣可以減少溝通協調成本,加快變更迭代速度,這是遵循康威定律的體現。下圖展示了一種BFF和團隊職責邊界劃分方案。

架構的本質是管理複雜性,微服務本身也是架構演化的結果

Sam還指出,對於一些跨橫切面的關注點(cross cutting concerns),例如路由,安全認證,日誌監控分析,限流等等,通常可由獨立的網關(Gateway)層負責(如Fig 6所示),由獨立基礎設施團隊運維,置於BFF之前,這樣在架構上可以做到職責單一和關注分離,讓BFF開發人員專注於聚合裁剪等業務功能,無需考慮跨橫切面功能。但是如果對運維成本和調用性能有額外考慮,跨橫切面的功能也可以直接做在BFF一層

架構的本質是管理複雜性,微服務本身也是架構演化的結果

獨立網關層負責跨橫切面功能

文末有關於微服務的系統學習路線和架構學習資料,有興趣的可以看看

三、攜程無線微服務案例分享

攜程網是一家旅遊行業的互聯網公司,其內部有約十幾個大小不同的事業部(也稱戰略事業單位,Strategic Business Unit,SBU)組成,例如機票,酒店,度假等等。三四年前,為迎合無線互聯網的趨勢,和很多其它互聯網公司一樣,公司成立了一個獨立的無線事業部(也是一個SBU),統一為整個公司開發無線應用。下面兩個圖分別是攜程無線H5應用的首頁,和最初的無線架構:

架構的本質是管理複雜性,微服務本身也是架構演化的結果

攜程無線H5首頁


架構的本質是管理複雜性,微服務本身也是架構演化的結果

最初的攜程無線架構

架構底層是企業傳統的SOA/ESB/DB服務,架構上層是用戶的無線設備,中間是用戶體驗適配層BFF。攜程針對兩類不同的用戶體驗分別做了兩個BFF:

  1. Mobile App BFF: 針對iOS,Android等Native和Hybrid應用場景,採用定製的TCP協議和二進制消息以提升網絡傳輸性能,
  2. H5 BFF:針對HTML5瀏覽器應用場景,採用標準REST/JSON協議通訊。

最初,攜程無線BFF是單塊的(Monolithic),BFF由無線事業部集中開發,涵蓋其它所有SBU(酒店、機票、度假等)的聚合裁剪邏輯。剛開始,攜程無線應用相對簡單,單塊BFF有優勢,例如開發、測試和部署集中簡單,運維和集群擴容也比較方便。

但是隨著時間的推移,特別是近兩年,使用無線應用的用戶數成倍增長,無線應用的功能也變得越來越複雜,康威定律逐漸發揮作用,無線SBU和其它業務SBU之間的溝通協調成本越來越高,相互之間還常常因溝通不暢而產生摩擦,交付效率越來越低。同時,單塊BFF還具有代碼邏輯耦合臃腫,集群故障概率高,技術棧綁死,阻礙快速創新等單塊架構固有的缺陷。

2014年,攜程對組織架構進行了一次調整,將原無線事業部拆分,將無線團隊打散並安排到各個SBU業務事業部中。為配合組織架構的調整,公司的技術架構團隊也將原來的單塊BFF架構升級到如下的面向體驗的微服務架構:

架構的本質是管理複雜性,微服務本身也是架構演化的結果

新架構中,原來的單塊BFF被拆分到各個SBU獨立開發、測試、部署和運維。新架構中引入了一個API網關層(API Gateway)

,是服務解耦自治的關鍵,主要負責服務反向路由,同時負責限流容錯、安全、日誌、監控等跨橫切面的公共邏輯。BFF解耦之後,攜程微服務架構和組織業務架構進一步對齊,職責更明確,交付效率和創新速度明顯加快。

文末有關於微服務的系統學習路線和架構學習資料,有興趣的可以看看

四、Netflix微服務架構分析

Netflix是一家美國的在線影像租賃服務提供商,早在2012-2013年左右,Netflix就已經建立起了比較成熟的微服務架構體系。值得一提的是,Netflix還把它的整個微服務技術棧開源出來貢獻給了社區,其中包括知名的開源服務網關Zuul,服務註冊發現框架Eureka,服務端框架Karyon,客戶端框架Ribbon,容錯組件Hystrix等等,可以說Netflix對微服務架構的發展起了重要的推動作用。下圖展示了Netflix的微服務技術棧,其中帶粉紅色標註的組件和Zuul都是開源的:

架構的本質是管理複雜性,微服務本身也是架構演化的結果

下圖是我對Netflix微服務技術棧的一個簡化和抽象,可見整個微服務體系的骨架:

架構的本質是管理複雜性,微服務本身也是架構演化的結果

Netflix的微服務體系可以簡化為兩層服務:

  1. 邊界服務層(Edge Service Layer),本質上就是BFF,適配前端各種用戶體驗的API層,
  2. 中間層服務(Middle Tier Service),Netflix後端的各種微服務的統稱。

Netflix的微服務體系由兩個重要的基礎設施支撐:

  1. 服務網關(API Gateway),是Netflix微服務的總入口,負責反向路由,安全,限流容錯,日誌監控等跨橫切面的功能,
  2. 服務註冊表(Service Registry),負責網關到邊界服務,邊界服務到中間層服務,以及後臺服務之間的軟路由和軟負載。

Netflix需要針對超過一千種的設備提供服務,這對他們的API層(也就是邊界服務層或者BFF層)的設計提出了很大的挑戰,為了應對這種挑戰,Netflix的UI團隊和API團隊通力協作,由API團隊提供通用的API運行時平臺(有點類似PaaS for API的概念),UI團隊則在API運行時平臺上針對不同設備利用動態腳本開發不同的API端點,這種模式最大化了UI團隊的效率和靈活性,如下圖所示:

架構的本質是管理複雜性,微服務本身也是架構演化的結果

UI和API團隊協同開發API

Netflix的API運行時平臺內部細節和運作方式如下圖所示:

架構的本質是管理複雜性,微服務本身也是架構演化的結果

Netflix的API運行時平臺由API團隊負責開發和運維,其中內置支持:

  1. 通用的調用後臺服務的SDK;
  2. 支持併發調用多個後臺服務的異步服務層(基於RxJava);
  3. 容錯組件Hystrix。

UI工程師利用Groovy腳本根據前端設備展示的需要開發API腳本,通過SDK調用後臺服務,對後臺服務和數據進行聚合裁剪,開發完成的腳本通過端點管理器上傳到API運行時平臺上,最後激活該腳本則對應的API端點就能生效對外提供服務。Netflix API運行時平臺也稱為動態腳本平臺(Dynamic Scripting Platform)。

Netflix應用採用前後分離架構,頁面等靜態資源置於CDN上,用戶設備從CDN直接加載頁面,交互時頁面直接從後臺邊界服務層獲取數據,如下圖所示:

架構的本質是管理複雜性,微服務本身也是架構演化的結果

下圖是Netflix API在AWS上的部署架構:

架構的本質是管理複雜性,微服務本身也是架構演化的結果

文末有關於微服務的系統學習路線和架構學習資料,有興趣的可以看看

五、SoundCloud微服務架構分析

SoundCloud是一家音頻分享網站,有點類似音頻界的YouTube,最近SoundCloud在SlideShare上分享了他們的微服務架構和實踐。

架構的本質是管理複雜性,微服務本身也是架構演化的結果

SoundCloud微服務架構一

上圖是從SoundCloud的一個ppt截取的微服務層次結構圖,和Netflix/攜程類似,兩個主要層次是:

  • 邊界服務層(Edge Layer),相當於BFF,針對不同場景體驗的適配層,例如第三方集成的Public API,嵌入頁面場景的Api-embedded,無線場景的Api-mobile和桌面應用場景的Api-v2。
  • 微服務層(Microservices),SoundCloud後臺微服務的統稱,例如messages、stats、likes服務等等。

下圖是從SoundCloud另一個PPT截取的微服務架構圖。

架構的本質是管理複雜性,微服務本身也是架構演化的結果

SoundCloud微服務架構二

有兩點值得關注:

  1. SoundCloud將Geoip、限流、安全認證等跨橫切面功能和BFF做在同一層,沒有像Netflix/攜程一樣做在獨立的網關層,SoundCloud的這一做法有
    性能優勢,但同時也增加了BFF層的複雜性;
  2. SoundCloud將後臺微服務又分為兩層,最底層的基礎服務層(Foundation Service Layer)和中間的增值服務層(Value-added Service Layer),這種分層方式是SoundCloud根據自己的需要提出的一種邏輯劃分。
  3. 文末有關於微服務的系統學習路線和架構學習資料,有興趣的可以看看

六、微服務架構不是免費的午餐

上面分享的三家公司都是體量比較大的互聯網公司,他們的業務量和團隊規模決定他們很難不採用微服務架構,但是對中小型規模的公司來說,這三家的架構未必是可以直接照搬的,個人認為,解決問題的scope不同,所採用的架構一般也不同,不能盲目照搬。

架構的本質是管理複雜性,微服務本身也是架構演化的結果

馬丁說,你必須長足夠高,才可以考慮使用微服務,這裡的高就是指基本的研發能力,包括:

  • 快速的環境提供(Rapid Provisioning)能力,理想有基於雲的環境提供能力。
  • 基本的監控 (Basic Monitoring)能力。
  • 快速的應用發佈(Rapid Application Deployment)能力。
  • DevOps文化。

在沒有建立起這些能力之前,勿輕易跟風采用微服務架構,上面分享的三家公司,都是在具備這些基礎研發能力的基礎上才開展微服務的。

架構的本質是管理複雜性,微服務本身也是架構演化的結果

馬丁指出,當業務不復雜,團隊規模不大的時候,單塊架構比微服務架構具有更高的生產率(productivity),原因在於建立微服務架構需要額外的開銷來支持和管理微服務,從而降低生產率;但是隨著業務複雜性的增加和團隊規模的擴大,單塊架構比微服務架構的生產率下降更趨明顯,當複雜性達到一個點,微服務架構的生產率會優於單塊架構,原因在於微服務的鬆散耦合自治特性減緩了生產率的下降趨勢。

注:馬丁在上圖的右下角提出了一個很有意思的觀點,團隊的技能是比單塊或者微服務架構的選擇更重要的因素。說白了,如果團隊能力不行,不管用單塊還是微服務,還是難於管理複雜性。

反過來,如果團隊能力強,不管用單塊還是微服務,都能找到好的管理複雜性的手段,所以說團隊的技能才是管理複雜性的關鍵

架構的本質是管理複雜性,微服務本身也是架構演化的結果

馬丁說,他不建議企業應用一開始就直接上微服務架構,原因一方面是支持微服務架構需要額外的開銷來管理分佈式複雜性,另一方面是剛開始系統複雜度和領域邊界是不清晰的,你不知道該如何正確的切分微服務,所以這種方案常常具有很高的失敗風險。

馬丁建議企業應用走單塊優先的架構思路,先輕裝上陣,贏得時間探索系統的複雜性和領域邊界,當複雜性增加時,拆出部分微服務,隨著團隊對服務邊界更加清晰和服務管理能力的提升,持續拆分出更多微服務,最終演化出微服務架構。

文末有關於微服務的系統學習路線和架構學習資料,有興趣的可以看看

七、總結

1、微服務架構是一種支持演化的自適應的架構,微服務架構本身也是演化的結果,架構演化的主要驅動因子是:

  • 經濟達爾文:從長遠看,只有那些能更好滿足客戶需求的企業才能生存。簡單講就是業務驅動,業務要求架構靈活易於變更和擴展,易於升級替換,發佈快速,高可用能應對不可預測的流量模式,能支持多樣的用戶設備和體驗,這樣才能加快業務創新的速度,贏得客戶和競爭優勢;
  • 無線、智能設備和雲等技術的進步和發展;
  • 康威定律,即企業的業務、組織和系統邊界要儘可能對齊,以業務領域和微服務為邊界的產品型跨職能團隊能更敏捷地響應市場需求。

2、系統架構的首要目標是管理複雜性,遵循良好的架構原理,如單一職責、有界上下文、關注分離、模塊化和分而治之,是管理複雜性的有效手段。在企業應用成長到一定規模以後,微服務架構是管理複雜性的一種行之有效的架構風格。

3、企業要不要用微服務,取決於你的業務複雜度和團隊規模,一般Monolith First。業界大型互聯網企業的微服務架構可以參考和學習,但是不能照搬,解決問題的scope不同,採用的架構也不同。

4、BFF(Backend For Frontend)是應對當前多種用戶體驗的一種模式和最佳實踐,BFF的主要作用是針對不同的用戶體驗對後臺服務和數據做聚合裁剪適配。用戶體驗適配層,BFF,API Orchestration Layer,Edge Service Layer,Device Wrapper Layer是相似概念。

5、Client -> API Gateway -> BFF -> Downstream Microservices,是面向體驗的微服務的標準參考架構。

6、特點:

企業後臺採用微服務架構,微服務可以採用不同的編程語言和不同的存儲機制;

企業前臺採用BFF模式對不同的用戶體驗(如桌面瀏覽器,Native App,平板響應式Web)進行適配;

企業後臺採集各種數據,集中存儲,再進行大數據建模、分析和預測,計算出來的數據再以微服務方式反哺給前臺頁面(例如商品推薦)。

架構的本質是管理複雜性,微服務本身也是架構演化的結果

7、系統化

最後這個學習路線圖分享給大家,還有一些架構學習資料,需要的可以去領取。

資料獲取方式:關注+轉發後,私信關鍵詞 【架構資料】即可獲取!重要的事情說三遍,轉發、轉發、轉發後再發私信,才可以拿到!

架構的本質是管理複雜性,微服務本身也是架構演化的結果

架構的本質是管理複雜性,微服務本身也是架構演化的結果


分享到:


相關文章: