系列文章
- .Net微服務實戰之技術選型篇
- .Net微服務實戰之技術架構分層篇
- .Net微服務實戰之DevOps篇
- .Net微服務實戰之負載均衡(上)
- .Net微服務實戰之CI/CD
- .Net微服務實戰之Kubernetes的搭建與使用
- .Net微服務實戰之負載均衡(下)
- .Net微服務實戰之必須得面對的分散式問題
- .Net微服務實戰之可觀測性
- 重新理解微服務之它還那麼純粹嗎?
前言
本文於 2022.6.29,首發於ITPUB 官方公眾號,作者陳珙,未經授權禁止轉載。如需轉載,請聯絡 ITPUB 公眾號。
上星期,我發了篇文章——《重新理解微服務之它還那麼純粹嗎?》,從微服務從他的過去、本質出發跟大家分享自己一些見解。此篇文章會從4個爭議比較多的微服務話題出發,再跟大家再分享一二。
原本兩篇文章是以一篇來寫的,但是原字數1萬7千多字,經過和DTCC的韓老師溝通後,最終拆成了兩部分。
寫在前頭
大家曾經有沒有遇過日常技術交流的時候,會討論某某技術之間的關係是什麼,某些技術是否應該用到微服務。我相信熱愛技術交流的您,就算不是在微服務這裡領域,或多或少都會跟其他同行會做一些爭議話題的探討,而且我敢肯定這些討論絕對熱火朝天。
今天我想從微服務的4個比較火熱的話題進行出發,與大家分享我對微服務的一些個人見解,這4個話題分別是:微服務來帶的新問題、微服務與SOA、微服務與DDD、是否有必要引入聚合層。這裡部分話題,在業界會存在一定的爭議性,例如DDD的引入、微服務與SOA的關係。
一千個人眼中有一千個哈姆雷特,不同的人以不同的視角去看待這些問題,都會擁有不同觀點與答案。觀點上,我們們求同存異,不盲目遵從別人的想法,也不自以為是的把自己當成標準。
當然了,我並不會為了個人見解而故意製造觀點與話題,更不會把我所有的觀點當成一個“所謂的”標準。因此在該篇文章,我會把多處理收集的資料梳理好放到文內,有理有據地結合自己的見解與大家分享一二。
這些內容可能是大家日常容易混淆的,也可能是大家多次糾結不知道如何做出選擇,因此我希望通過我該篇文章的分享,能給大家帶來新的觀點上的碰撞,或是見解上的共鳴。
微服務帶來的新問題
做技術選型就如網上購物一樣,即使知道了它的優點,還得看看它的差評。我們得多方面評估,事先知道團隊與業務是否能抵禦與承受“坑”的風險。
既然任何一樣技術都無法成為軟體工程的銀彈,那麼必然解決了某種問題的同時,也會帶來一些新問題,微服務也不例外。我回顧了下當時我實施時的難點確實有不少。不過,我個人認為微服務給我們帶來最核心的問題主要有三點,兩文化與一思維:
- 自動化文化
- 可觀測性文化
- 分散式系統思維
上面這三個問題,每個的內容單獨拿來出講的篇幅,都足以出一篇完整的文章甚至是書,基於此我會挑一些重點和大家分享。當然,幾乎每部分的文末,我會放入相關內容的文章外鏈,如果大家有興趣可以自行擴充套件閱讀。
自動化:避免重複的人力勞動
任何的架構模式,也是需要同等的開發模式與之配合的,隨著應用的拆分後服務的數量由量變引起質變,因而需要接受自動化來代替從前的“人工處理”,包括服務的部署、服務註冊發現等等。自動化,是軟體工程的其中一種處理手段,允許團隊採用主流的工具、流程形成一套自動化機制,從而減少重複性工作、減少人力干預的不確定性因素。
這裡說說我對軟體工程的理解:通過多人協作、有目標、有步驟、有計劃的,並使用科學方法論指導開發與維護程式的這個過程,也可以換成一條公式表達:軟體工程 = 工具 + 流程 + 模式。
無論是我們討論的這些“事”、技術工具,還是流程制度都是需要人(團隊組織)的參與,人的延申就是團隊與文化,就如上述所說的軟體工程是多人協作的工作,只有當然團隊目標一致,共同負責承擔團隊的專案,共同接受同一種文化才能很好的實施自動化。
我簡單舉個例子:如同多匹馬拉車一樣,只有它們都有共同的目標的時候,才能快速拉車到目的,如果它們一匹向東一匹西,只會讓馬車無法前行甚至四分五裂。
說到這裡有些人覺得疑惑,自動化這種能給團隊省時省力、減少重複工作量、增加幸福度的技術難道還有人或者團隊會抗拒的?是的,還真的有。
我曾經就接觸過幾個團隊的Leader,他們的團隊都是推行自動化失敗了,失敗的原因就在於成員不配合,成員拒絕配合的理由是:沒有自己親手去做總覺得機器不靠譜。我們先忽略他們的想法是對是錯,回到團隊與文化,從上面可知,統一團隊的目標一致性是有必要的,作為技術領導者推行優良的方案,是我們的職責之一。如果團隊成員無法配合,導致推行受阻,我們一共有三種應對策略:激勵、考核和逐步試行。
如果有條件的公司可以設定獎金激勵,如果有績效考核的,可以將自動化的實施納入考核目標,如果這倆都沒有,那就選取團隊裡願意改變的同事牽頭試行,假如使用過後都說好,那麼會更有說服力。
這部分就說到這裡吧,基於此話題的內容比較多,廣而泛,篇幅有限,這裡分享一篇我自己曾分享過的內容《.Net微服務實戰之DevOps篇》,如有感興趣的朋友,可看完整篇文章後自行有選擇性、針對性地擴充套件閱讀。
可觀測性:提高團隊對系統運作的資訊量
如果說自動化是給團隊帶來穩定性,減輕工作量的,那麼可觀測性就是提高團隊對系統運作的資訊量。建立可觀測性的這項工作,雖然無法直接給系統帶來健壯性,但能夠使我們通過這些資訊充分地瞭解到系統正在運作的情況,以至於最大程度地做出最合適的定位、判斷與決策。
在單體應用的場景下,我們也是需要可觀測性的,但是單體的架構相對簡單,專案除錯也更加便捷,無論是從複雜度和規模的角度來看,單體跟微服務相比都要低不少,也因此單體對可觀測性的需要,相比於微服務顯得沒那麼重要。
而我們只要進行了微服務實施後,因為應用被拆分成了細粒度,從而導致了架構從量變引起質變,這個時候可觀測性的作用在微服務場景下被“無限放大”,也因此我們利用"可觀測性",給與我們提供應用與伺服器的監控、快速跟蹤與問題定位的功能。
可觀測性——可以由系統的外部輸出推斷其內部狀態的程度,在軟體系統中,可觀察性是指能夠收集有關程式執行、模組內部狀態以及元件之間通訊的資料
而可觀測性三個維度組成:日誌(logging)、跟蹤( tracing)、指標(Metrics)。
日誌(logging)的定義特徵是它記錄離散事件,目的是通過這些記錄後分析出程式的行為。
跟蹤( tracing)的定義特徵是它處理請求範圍內的資訊,目的是排查故障。
指標(Metrics)的定義特徵是它們是可聚合的,目的是監控和預警。
可觀測性 |
型別 |
名稱 |
跟蹤( tracing) |
分散式鏈路跟蹤 |
SkyWalking |
日誌(logging) |
日誌系統 |
ES+Filebeat+kibana |
指標(Metrics) |
系統監控 |
Prometheus |
因此基於上述總結,有日誌記錄才能清楚知道當前系統的執行狀況和具體問題;指標是給與後續做優化和定位偶發性問題的一些參考,沒指標參考就沒標準;我們平常做得多的除錯、檢視呼叫棧也是跟蹤的一種,但是在分散式時代,更多考量的是跨程式通訊的呼叫鏈路。
日常有小夥伴曾問過我,如果出了那些很奇怪的問題,應該怎麼定位、排查,本質上其實還是得提高我們對這個問題或系統的資訊量。
例如:是哪個模組、介面出問題?具體伺服器表現的情況是怎樣?CPU還是IOPS高?具體報錯是什麼?
你看,說白了還是可觀測性的三個要素日誌、跟蹤、指標。我們在工作中只有靈活結合這三者,才能提高我們對系統執行情況的資訊量,資訊量越高思考的越是更加全面,才能儘可能地減少“不知道問題出在哪”的狀況,所以當我們不清楚具體發生問題的原因時,建議你側重做一件事:就是儘可能想辦法,提高我們對問題與系統的資訊量。
新思維:不可避免的分散式系統問題
上文的自動化和可觀測性,主要偏向於運維層面,而作為後端開發人員更加關注的是資料與應用服務的層面,特別是服務的拆分後,資料的一致性該如何處理。我相信這問題困擾著不少的後端開發,接下來我將從冪等性、資料的一致性的讀與寫三個方向,跟大家分享一二。
冪等性
冪等性的定義——相同的引數在同一個方法裡,無論執行一次還是多次都會響應相同的結果
對於查詢和刪除的場景都有天然的冪等性,那麼我們考慮冪等性的處理,更多是關注於新增資料與更新資料。
新增資料缺乏冪等性,則會因為網路抖動導致請求重試或者是客戶端重複點選,而引發的資料寫入重複,其解決方案也相對簡單,只要從客戶端生成主鍵傳給後端API 就可以解決,在這裡得注意一點,只有請求成功或者主動重新整理才會重新生成主鍵。
更新資料缺乏冪等性,主要會造成兩種情況,數值錯誤自增和ABA問題。首先,數值錯誤自增,可以結合事務憑據與新增冪等性的方式解決。
而ABA問題,解決方案相對簡單,可以在更新操作時帶上版本號判斷進行解決。
ABA問題對某條記錄先更新了A資料,緊接著又更新了B資料,理應是B是最新的,但是因為其他客觀原因使介面Retry或者別的問題,導致A資料再次請求覆蓋了B。
冪等性處理方案 |
||
場景 |
問題 |
方案 |
新建資料 |
重複建立 |
由呼叫端預生成訂單號,唯一鍵約束 |
更新資料 |
ABA覆蓋問題 |
新增版本號判斷 |
金額自增 |
使用流水憑據 |
資料一致性(讀)
資料一致性讀,其實說白了就是做資料關聯,從我過往用的解決方案來看共有三種,應用層的介面聚合資料、把更新頻率低的欄位冗餘儲存、把資料庫同步到一臺伺服器進行SQL聯表處理,每種方式各有優缺點,我結合切身體會和過往經驗,以表格方式整理呈現出來,你可以根據業務場景自行選擇解決方案。
資料關聯方案 |
|||
方案名稱 |
方案描述 |
優點 |
缺點 |
應用層資料聚合 |
分別呼叫查詢API,在業務邏輯層組裝,適用於簡單的關聯。 |
實現簡單 |
該方案只能適合簡單的查詢過濾,以主表為驅動的關聯 |
冗餘設計(反正規化) |
在目標表新增冗餘欄位,適用於記錄遞增的,不適用於冗餘欄位更新頻繁,實現起來簡單,有擴充套件性問題 |
實現簡單,以應用層資料聚合方案有更多的過濾條件 |
冗餘的欄位如果更新存在同步問題,該方案適用於更新頻繁少的遞增日誌類資料 |
資料庫從庫整合 |
通過主從同步把相關表同步到一臺伺服器做跨庫查詢,適用於複雜查詢、報表類的,有技術複雜度,從長遠收益來看能應對多種場景 |
通過強大的SQL解決複雜的報表類查詢 |
擁有技術複雜度,需要資料庫主從處理 |
資料一致性(寫)
寫的資料一致性,其實就是分散式事務,主流的方案有TCC、本地訊息表(基於訊息可靠的最終一致性)、非同步請求/回撥。其他的多數是基於以上幾種方法的變種,例如RocketMQ的訊息事務,就是TCC+本地訊息表的變種。篇幅有限,這裡分享一篇我曾經編寫的文章《.Net微服務實戰之必須得面對的分散式問題》。
分散式事務方案,用文字描述起來相對比較吃力,因此我通過流程圖代替文字描述展示給大家。下方表格是我對這三種方案的優缺點與使用場景的總結。
分散式事務方案 |
|||
名稱 |
場景 |
優點 |
缺點 |
非同步請求/回撥 |
跨網路環境、同網路環境 |
實現簡單 |
強業務 |
TCC |
跨網路環境、同網路環境 |
有現成的框架、實現簡單 |
強業務 |
基於訊息可靠的最終一致性 |
同網路環境 |
有現成的框架、通用性強 |
中介軟體依賴 |
小結
從"拆"的層面來看,微服務的思想與優勢給與開發人員帶來了更多的便捷性,如技術細節的隱藏與認知負擔的降低,使得開發人員更加關注自己負責業務程式碼的迭代。
但是,拆了後還得重新整合,如果拆了無法整合,那麼這樣的設計是沒有意義的。從"整合"的層面,微服務大大提高了對架構師技能的要求,從通訊互動到分散式問題,從自動化工程到可觀測性,每一項對於架構師都是一種新的挑戰。
聊到微服務總繞不過SOA
無論是過去還是現在,只要聊到微服務總有個繞不過去的坎,那就是SOA。接下來,我會結合《Microservices》原文(https://martinfowler.com/articles/microservices.html#MicroservicesAndSoa)的[Smart endpoints and dumb pipes]模組,簡單聊聊微服務與SOA的之間的關係,有助於大家更好地瞭解為何微服務比SOA更容易實施與盛行。
在《Microservices》原文裡有一個模組的標題是Smart endpoints and dumb pipes,如果用翻譯直譯成中文是[智慧端點和啞管道],我結合了自己的經驗並查閱了多種資料,最終認為[強服務和弱通訊]作為它的翻譯才更加合適。
微服務的[強服務和弱通訊],與SOA的[弱服務和強通訊]是與之對應的,而SOA架構的核心是ESB,ESB主要功能有訊息路由、協議轉換、訊息轉換和應用業務規則的複雜。仔細觀察下來,ESB基本上把微服務的基礎設施該做的都做了,如此高的技術複雜度,也是導致SOA在過去那些年無法普及跟實施的根本原因。
ESB的大而全的特點,在文中描述到SOA的通訊是“聰明的”(smart pipes),而我也因為ESB的特點給SOA的翻譯是“強通訊”。此外,我翻譯的微服務的“弱通訊”,並不代表通訊的功能有限,而真正的意義是弱化協議差異,使用統一、輕量級的通訊協議,減少差異化、降低技術難度。
總地來說,基於兩者在通訊層面的對比,我們因此能總結出它們本質上的差異:SOA基於配置,微服務則基於約定。
關係的分類
既然上面已經談到了微服務與SOA之間的對比,接下來,又不得不提SOA與微服務的關係了。我從多個方面的資料梳理後,總結出有這樣兩種看法:
- 微服務是SOA的最佳實踐(出自維基百科)—— 微服務是SOA的演進版,粒度更細,基礎設施去中心化。
- 微服務拒絕SOA的標籤(出自馬丁福勒的《Microservices》原文)——微服務與SOA,是兩個完全不同的架構風格,只不過剛好長得像。
場景與目的
我相信,不少朋友看到SOA與微服務關係方面的話題時,肯定第一時間在想,無論是維基百科還是百度,都是寫著微服務是SOA的演化這還要說?是的,人云亦云的,大家聽多了看多了,不妨從新的觀點與角度看待一下問題,這樣或許會有新的碰撞與共鳴。
大家認為,微服務是SOA的演進版的理由也比較簡單,因為微服務基礎設施只不過是把SOA的ESB拆了,而微服務粒度更細,SOA更粗。從表面看起來的確是這麼一回事,但是我認為,要看清楚它們關係的本質,就得從兩者各自的處理場景目的出發。
首先從微服務角度出發,因為單體應用的大而全的高耦合與臃腫,隨著業務的發展迭代的時間越久,就會有各種各樣的問題,因此通過把應用拆成了多個"小"的服務,這裡使用到了化繁為簡、分而治之的思想,解決原有單體的“痛點”和“難點”。
接著從SOA的角度出發,在當時那個年代,希望把各種異構的系統給整合起來,這些異構的系統,有可能是從其他地方買的,也有可能是研發的,也有可能是找外包做的,因緣由存在各種不確定性,所以希望通過一個"聰明的"ESB解決所有的"愚蠢的"問題,也是因此ESB的高複雜度,導致當年SOA那會只是炒得火熱,卻無法普遍落實。
總地來說,微服務以拆與約定作為出發點,而SOA是以整合與配置作為出發點,所以我個人認為從它們的出發點與目的的角度出發,直接決定了它們在本質上是完全不同的架構風格。所以我更加傾向於《Microservices》原文提到的看法,微服務的倡導者拒絕SOA這個標籤的。
微服務與DDD的爭議
要是說SOA是微服務理不清的過去,那麼DDD更是微服務的一塊攔路石。攔住的不是技術人員對它們的熱情,而是它們之間扯不清的“捆綁銷售”。
《Microservices》原文、《微服務設計》、《領域驅動設計精粹》,都有涉及到DDD對微服務劃分的參考。DDD戰略上的化繁為簡,與微服務的分而治之,這兩者的思想,可以說是不謀而合。成就了彼此,但是它們是否必須密不可分,又或者說無DDD就無微服務的說法呢?我是這麼認為的。
DDD(領域驅動設計)的過去
2004年,埃裡克•埃文斯(Eric Evans)發表了《領域驅動設計》一書簡稱DDD(domain-driven design ),自DDD提出後在軟體開發領域一直處於SOA相似的尷尬地位——宣傳得火熱,真正用的少。
隨著微服務架構的興起,DDD才迎來了自己的時代。在上文提到三本書(《Microservices》原文、《微服務設計》、《領域驅動設計精粹》),都有涉及到使用DDD戰略來識別邊界上下文,從而劃分服務。總地來說,DDD並不是什麼新穎的技術,當年許多佈道者也沒有把它帶火,如今卻靠著微服務流行起來而加速了DDD的盛行。
但是,DDD的盛行並非它所有的一切,我總結了DDD的一些核心概念,希望在我詳細敘述前,可以幫助到你快速瞭解DDD,以便於對後續內容有個更好的理解:
領域驅動設計的本質是,打破業務與開發之間溝通壁壘,建立通用語言;從而在戰略設計與戰術設計兩個維度上使用化繁為簡手段將通用語言逐步拆解成領域模型;從而確定業務與應用的邊界,保證業務模型與程式碼模型的一致性。
戰略設計,從業務視角出發,建立業務領域模型,劃分領域邊界,建立通用語言的界限上下文,界限上下文可以作為微服務設計的參考邊界。
戰術設計,從技術視角出發,側重於領域模型的技術實現,完成軟體開發和落地,例如我們常討論的聚合根、實體、值物件、領域服務等程式碼邏輯的設計與實現。
結合上述的DDD概念知識與[業務與團隊]模組所敘述,我們可以得到以下結論:業務需求是作為我們設計的核心輸入之一,要做好領域驅動設計,並非取決於對它本身的概念掌握程度如何,而在於如何使用這些方法論瞭解清楚業務需求後,進行正確的領域建模,就算對DDD的概念再熟悉不過,要是對領域業務缺乏瞭解,結果也是無法正確建模的,那跟用不用DDD其實已經沒什麼區別了,所以我認為這種做法與結果是本末倒置的。
PS:[業務與團隊]這個模組是先前發表的文章《重新理解微服務之溫故》裡的內容,兩文之間沒有特別的前後關聯性,有興趣的朋友,可以閱讀完本文後可自行進行擴充套件閱讀。
【維基百科】領域驅動的侷限性,為了幫助保證模型能作為一個單純並有用的語言結構,團隊通常必須在領域模型中實現大量的隔離和封裝。因此,基於領域驅動設計的系統可能會花費相對較高的成本。雖然域驅動設計提供了許多技術優勢,如可維護性,但 Microsoft 建議僅將它應用於複雜領域中,在這些複雜領域中,通過模型和語言處理能夠在複雜資訊中提供交流便利性的,並且能夠該領域達成共識。
文中我也多次宣告軟體工程是沒有“技術銀彈”的,結合上面領域驅動的侷限性(維基百科)的敘述,DDD同樣也有它的適用場景與侷限性,像軍工、金融等這些領域,就比較適合使用DDD,因為它們都具備了這兩個特徵:
- 生命週期長(投入產出比)
- 邏輯足夠複雜(使用複雜對抗複雜)
而網際網路系統擁有需求高頻變動性、快速試錯和定製性,DDD是否需要引入,大家見仁見智。
DDD戰略的重要性
首先,DDD的戰略設計是可以使用指導劃分微服務,這點是毋庸置疑的,因為微服務的分而治之的思想,與DDD的化繁為簡,的確是不謀而合。
然而,我接觸過不少DDD的熱衷者,只要聊起DDD,全部都是DDD的概念與術語,同時把DDD戰術設計代入為微服務的全部,一開口的就是概念術語什麼倉儲、什麼領域服務、什麼聚合根,Abp框架,盡扯跟微服務設計沒有半毛錢關係的東西,微服務的服務治理、分散式需要面對的資料一致性、冪等性和自動化部署卻閉口不談。
戰術設計其實就是為了落實物件導向設計與程式設計、從業務模型到程式碼模型的翻譯,說通俗點就是針對單個服務與應用的設計,而由微服務架構風格設計的系統是屬於分散式系統,應更多關注跨程式的互動與服務的整合。
因此,DDD戰術設計是否引入,完全是看該服務對於系統的重要性。
在《微服務設計》一書提到過,微服務裡的服務的複雜度能在兩個星期內重構完成的。如果遵從DDD戰術設計思想的應用,那麼是使用複雜對抗複雜,因而會增加服務本身的複雜度。從個人的角度來看,DDD戰術與微服務拆分後降低複雜度的出發點,相違背。
因此我實施微服務的時候,最終還只是以戰略設計引入到微服務設計裡,在期間我嘗試使用了事件風暴與其他同事合作,幫助識別我業務邊界從而確定界限上下文,而DDD戰術則根據日後業務穩定,並且邊界清晰後,再考慮選擇性引入重構。事件風暴是一個從拆解到整合的過程,過程中需要領域專家(需求提出者)和技術實踐者協作完成領域建模。
一般採用場景分析和用例分析儘可能分解出領域物件(實體、命令、事件),可以從交流的過程中提取出領域專家(需求提出者)口中的名詞、動作、觸發事件等,這是一個拆解的過程。
在軟體工程裡沒有銀彈,微服務不是,DDD也不是,我們所做的永遠提供的是解決方案,同一個問題能有很多種解決手段,但是同一種解決手段並不能解決所有問題。
微服務需要引入聚合服務層嗎?
這是我們們這篇文章的最後一個話題了,也是我在微服務實踐時被同行問得最多的一個問題。
回顧我身邊,不同的時間,不同的人,實施同一種微服務架構風格,都問過我同一個問題:他們網上找了很多資料,聚合服務層有的說引入,有的說不需要,那麼,究竟微服務是否真的需要引入聚合服務層呢?
說句實話,這個問題也曾經困擾過我。經不斷的積累,我想我可以給這個問題一個明確的答案了:根據系統的複雜度與場景進行取捨,接下來,我將詳細敘述下我的思考結果。
API閘道器的型別
API閘道器可以作為多個微服務提供統一入口,它的思想類似物件導向設計的外觀模式,API 閘道器也稱為“面向前端的後端(BFF)”,因為它是為了滿足客戶端的介面整合需求而出現的。在《Microservices-Architecture-for-Containerized-NET-Applications》一書裡有這樣個觀點,認為API閘道器主要分兩種型別:
- 基礎設施型API閘道器
- 自定義業務API閘道器
基礎設施型API閘道器比較容易理解,我舉個例子估計你就秒懂了,Kong 和 APISIX。這種型別的API閘道器主要把服務具有相同的功能抽象到上游服務,像鑑權、日誌、限流、熔斷等通用功能,可以避免每個服務都需要去重新的實現這些相同的功能。
自定義業務API閘道器,其實就是把多個微服務,適配成方便客戶端使用的API服務,避免客戶端組裝過多的API導致過於臃腫,也就是我們們上面說的聚合服務層,也有稱之為面向前端的後端(BFF)。
取捨與選擇
有些朋友一看,既然能減少客戶端的工作量和複雜度那這個不是好事麼,還需要思考是否要引入?大家可別忘記了,在上文,我們多次提到了微服務的核心點——自治性。
如果在原有的基礎上加多了一層新的微服務,那麼上游微服務就會受到下游微服務的更新而有所影響,如果下游服務介面有更新,上游服務也可能跟著一起更新,因此丟失了自治性。除此之外增加了呼叫鏈長度,也會降低系統整體的可用性。
無論用和不用好像都有問題,該怎麼辦?取捨!
作為一個架構師,大部分的工作就是根據問題場景選擇合適的處理方案,因為大部分的方案是無法做到“完美的”,因此我們很多時候還得做出一定程度的取捨。
從個人的角度認為,如果多個業務需要客戶端組合大於等於3個介面,我們可以捨棄部分自治性而選擇引入BFF,以此來降低客戶端對接的複雜度。如果客戶端的業務相對比較簡單,BFF則不需要引入,那可以最大程度的保證自治性。因此在開始設計微服務的時候,在不明確的情況可以暫時不需要考慮,隨著業務系統的迭代,系統複雜度越來越高,我們再考慮BFF的引入。
基礎設施型API閘道器與BFF兩者的存在不是非此即彼的,因為基礎設施型API閘道器不影響微服務的自治性,因此可以獨立於BFF的選擇,是否引入也取決於團隊的運維支撐程度如何,運維能力足夠則使用中介軟體支撐,運維能力有限,則在微服務的程式碼裡實現。
小結
總上文可見,方案是沒有“完美的”,設計只有"合適"與"不合適”,沒有“對"與"錯",架構師永遠是在"取"與"舍"之間扎掙,而促使我們能做出那一次又一次的合適的選擇,只有積累與經驗。
結語
該篇文章到這裡就差不多結束了,我始終認為一圖勝千言,因此我在文中基於上述分享的知識點,給大家做了個腦圖,以便於幫助你回顧與總結。
微服務與DDD的見解,我也是再三思考了才打算寫出來,我清楚地知道有不少的DDD熱衷者認為這門技術是多麼的“神聖”,當然曾經我也是。
但是,隨著自己使用、接觸的技術越多,越是發現技術並不是那麼的唯一、神聖,促使我們能在這條道路走得更高更遠的,是我們們的思維,是我們對這些技術做出適當的選擇與使用,而不是想著“一招鮮吃遍天”,我們是技術的創造者與使用者,而不是概念名詞的搬運工。
該型別的話題與見解,每個人接觸後的解讀可能都不一樣,我的不一定是標準,僅是我自己觀點上的分享,希望能與你產生見解上的碰撞與共鳴。
微服務是否需要引入聚合服務層這個例子,可以作為架構師日常工作——取捨與選擇的縮影,通過這個例子我分享了API閘道器的型別,並且結合我的架構設計方法論,從取捨與選擇回答了這個問題,我們們可以根據自己問題的場景選擇合適的方案進行應對。
好了,到這裡我們就要結束了,非常感謝你耐心的閱讀,我們在後面的分享再見。同時期待後續的某幾個時段裡,我與你能夠有更多思想上的交流、碰撞。如果願意分享,這一講也歡迎轉發給你的朋友,和他一起討論。
還有,對這一講的內容分享,有疑問或是不同的差異化、多元化想法,可以提出來,留言區裡,我們多交流。