微服務架構落地及其演進
一、應用服務架構演進及微服務架構介紹
1.1 應用架構的演進歷程
應用服務架構一直處於不斷演進的過程中,上圖通過對比5種比較主流的架構模式,展示應用架構的演進歷程和變化。
- 單體架構(All in One)。在業務發展初期,為了快速落地應用,滿足客戶需求,一般會使用All in One的單體架構。單體架構的特點是:所有模組都耦合在一個程序裡,系統完全封閉且很複雜,牽一髮動全域性。
- 豎井式架構(Vertical Application)。隨著業務的增長,單體架構越來越臃腫,我們對系統做了垂直化的拆分,應用架構進入第二階段即豎井式架構。豎井式架構,就是根據業務屬性將一個大的單體拆分成一些不同的模組或子系統,子系統之間沒有直接關聯。豎井式架構依然存在緊耦合的問題,系統也是完全封閉的,且存在大量的重複程式碼拷貝及模組功能需大量重複造輪子的情況。
單體架構和豎井式架構都是圍繞web容器打包及部署的架構模式,隨著業務的快速發展,要求實現服務的快速迭代和快速交付,應用架構也由此演進為以服務為中心的架構模式。主流的面向服務的架構模式有:RPC架構、ESB中心化架構和微服務架構。
- RPC架構。RPC架構在現在的應用系統中還是比較常見的架構模式,適用於高併發場景,效能比較好。Dubbo就是一個典型的RPC架構。RPC架構也存在一些問題:通過共享分散式物件實現遠端方法呼叫,如果在其中一個物件裡新增一個屬性,就會對共享物件的生產者與消費者產生影響,所以RPC架構也是緊耦合的模式,系統互動採用RPC私有TCP協議,服務生產者和消費者存在強程式碼依賴,異構系統整合不友好。
- ESB中心化架構。ESB中心化架構實現了鬆耦合,依賴於ESB訊息匯流排技術實現異構系統的資訊互動和整合集中式架構管理,因此它雖然是面向服務的,但它本質上依舊是一箇中心化的架構。其優勢在於:基於WebService技術,重量級的訊息通訊機制,我們稱之為“智慧管道啞終端”,當團隊規模比較大、要實現異構系統整合時,它可以提供統一的解決方案和技術實現方式,快速整合異構系統對外服務。ESB中心化架構的問題也比較明顯:中心化架構難以滿足靈活性的服務迭代和需求交付。
- 微服務架構。微服務架構實現了系統解耦和持續整合,有清晰的服務邊界,粒度相對ESB架構和傳統SOA架構來說更小,使用輕量級的通訊機制互動,具備更強的擴充套件性和彈性,能夠更靈活、更快響應業務變化。
通過上述對比,我們不難發現,應用服務架構是在不斷演進的,而且其演進背後存在一定的邏輯,服務架構的演進主要取決於以下2個維度:
- 業務維度,技術架構是由業務發展所處的時期和階段決定的,技術架構要能夠解決業務發展過程中的痛點。在進行架構選型時,需要考慮這個架構是否能滿足當前業務的需求,業務需求能否隨著架構的演進實現增量式的迭代。
- 技術維度,一方面要滿足非功能需求,使得業務快速跟上技術生態的發展;另一方面出於商業的技術考量,比如去IOE、 去V、 採用開源的技術解決方案的需求,逐漸完成服務底層使用的商業軟體的技術隔離,滿足業務快速交付。
1.2 微服務架構的定義
關於微服務的定義,此處引用ThoughtWorks首席科學家Martin Fowler給出的描述。
其中以下特性值得特別注意:
- 微服務架構是一種架構模式,提倡將單⼀應⽤程式劃分成⼀組⼩的服務。
- 服務之間採用輕量級的通訊機制。
- 服務可以獨立部署。
- 應當儘量避免統⼀的、集中式的服務管理機制。
- 具體的⼀個服務可以選擇合適的語⾔、⼯具對其進⾏構建。
Martin Fowler對於微服務架構的表述更偏向學術上的定義,沒有給出明確的落地標準或規範,只是提供了一些構建微服務架構的原則。
1)面向開發者和業務實現
- 拆分成粒度小的服務。
- 各自獨立的程序實現服務執行隔離。
- 服務執行通過輕量級的基於HTTP協議的RESTful API的通訊機制進行。
- 服務關注圍繞業務領域之上構建。
2)面向服務的交付和運維
- 在服務交付方式上,強調可獨立部署。
- 支援去中心化的設計,服務一般不需要集中化的管理。
1.3 如何篩選微服務
微服務架構模式有如此多的優點,那是不是所有的業務都要採用這種架構模式呢?又該如何篩選微服務?
左邊圖中,橫座標代表系統複雜度、縱座標代表開發生產力、藍色線表示微服務架構、綠色線表示單體架構。由圖可知,當專案複雜度較低時,單體架構的生產力更高;隨著專案複雜度越來越高,單體架構的生產力逐漸下降,微服務架構的生產力則顯著提高。
1)3種場景可以考慮使用微服務(Are you tall enough? )
- 規模大,團隊超過10人。
- 業務複雜度高,系統超過5個子模組。
- 需要長期演進,專案週期超過半年。
2)其他因素篩選微服務
- 軟體功能變化頻繁,以快速迭代、縮短交付週期為核心的業務。
- 模組有獨立的生命週期,微服務強調服務複用,減少重複造輪子,實現降本增效。
- 有獨立的隔離性需求和擴充套件性需求(容錯)。
- 簡化的外部依賴。比如Facade模式場景,後端系統使用統一的對外暴露的形式提供服務。
1.4 如何拆分構建微服務
鑑別出哪些業務需要使用微服務架構模式後,需要決定如何拆分和構建微服務。
1)服務拆分
如何進行服務拆分,是在微服務過程中業務方經常會問到的問題。
其實很多團隊已經開始在做一些微服務化的工作,比如把大的工程拆分成不同的模組或子系統,這種對業務模組進行的靜態劃分,相當於已經完成了微服務改造的第一步拆分。
上圖是DDD(領域驅動設計)的開發模式,如果業務方案已經確定採用微服務的架構模式,在整個工程領域我們傾向於使用DDD模式來對業務架構和服務進行拆分。
DDD是基於領域模型的建模而不是資料庫表驅動的建模,需要我們對業務領域有深刻的洞察,瞭解服務的邊界和上下文資訊傳遞。
康威定律指出:在微服務架構和設計系統組織,其產生的設計等價於組織間的溝通結構。就是說微服務架構不僅是技術上的演進,同時對使用技術的組織提出了要求,拆分的服務是我們和服務之間的溝通方式。
2)微服務構建
我們採用微服務的12因子作為微服務建設的架構原則。微服務的12因子也叫雲原生12因子,它提供了一種業務上雲或微服務改造的最佳實踐。重點介紹其中幾個因子:
- 基準程式碼,建議專案使用一份基準程式碼、多份部署。專案在拆分時可能會存在多份基準程式碼,造成大量重複性的不同版本的程式碼共存的現象。在進行微服務構建時,需要把公共服務和公共程式碼抽取出來,統一支撐不同版本的業務。
- 顯式依賴,顯式宣告依賴關係。對於 Java 程式,在 Gradle 或者Maven中寫明依賴關係;
- 配置,在環境中儲存配置。根據當前的環境變數決定使用什麼樣的配置檔案。
- 後端服務,把後端服務當成一個附加資源。
- 構建、釋出、執行的分離機制,強調服務和構建在執行時,不可以直接修改執行中的程式碼,而是需要通過構建釋出流程統一發布。
- 無狀態程序,以一個或多個無狀態的程序執行應用。
1.5 微服務架構2種建設思路
微服務看起來非常好,但其實是需要一個技術體系或平臺體系來支撐的,如果沒有這樣一個服務架構平臺體系的建設,不推薦使用微服務。
微服務架構建設分為2種思路:SDK模式、ServiceMesh模式。
1)SDK模式
典型代表是SpringCloud,SpringCloud是基於SpringBoot的一整套實現微服務的框架。SDK模式的底層執行平臺可以是PaaS平臺,也可以是Kuberneters平臺或Docker容器。
- 優勢:面向應用和開發人員,定製化、協議支援靈活,適合完全自治的服務狀態,方便線下除錯,對作業系統平臺無依賴。
- 缺點:應用需引入額外SDK依賴包,SDK本身佔用記憶體及系統資源,對業務是侵入性的;需要構建微服務基礎設施做業務能力支撐;需要使用SideCar模式實現異構系統整合。
2)ServiceMesh模式
Istio 是ServiceMesh模式的典型代表。ServiceMesh模式的優缺點與SDK模式正好相反。
- 優勢:不需要額外引入SDK依賴包,對應用無侵入,且對Kubernetes天然友好支援。
- 缺點:部署比較複雜,對底層系統有一定的依賴;通訊協議型別支援受限,需要依賴Mesh平臺相容。
二、SpringCloud微服務生態體系介紹
SpringCloud是基於SpringBoot發展而來的一整套成熟的微服務架構解決方案。SpringCloud具有以下優勢:
- 面向開發者,以開發者為中心,開發者生態友好。
- 以Java技術棧為主要開發語言,程式碼可複用,微服務轉型成本低。
- 基礎設施完備,提供端到端的微服務架構解決方案。
- 有很多大廠做背書,如Pivital、Netflix,、alibaba等公司都是其生態和原始碼貢獻者,技術經歷過大規模商業應用的考驗。
2.1 SpringCloud的技術生態
SpringCloud本身也是一個逐漸演進的架構模式:最早是基於IOC/AOP的程式設計思想產生的;然後在Spring的基礎上發展出SpringBoot,基於註解的方式實現快速的應用開發;後來在SpringBoot的基礎上開發出SpringCloud底層微服務構架。
上圖展示了SpringCloud的技術生態,SpringCloud技術棧包含了很多技術模組,比如Ribbon、Zuul、Eureka、SpringCloud Stream等,這些技術模組共同組成了SpringCloud生態圈,為開發者提供豐富的微服務架構基礎設施支撐。
2.2 微服務和SpirngCloud架構的複雜性
微服務和SpirngCloud的架構是比較複雜的,如配置管理、服務註冊與發現、API閘道器、打包部署排程、安全、服務故障自愈、流量控制和彈性伸縮等非功能需求,都是微服務需要包含的架構模組。上圖中藍色字表示SpirngCloud、Kubernetes等用來解決雲原生和微服務架構問題的技術方案。
從圖中可以看出微服務架構的複雜性,要想實現一套微服務架構來支撐和交付業務,需要在底層封裝很多基礎元件,構建一套底層基礎架構來隔離底層的非功能需求,做到讓業務系統無感知、平滑地對外提供服務。
三、宜信微服務架構和SIA閘道器的4種模式
SpringCloud提供的框架或基礎設施是一個半成品,我們在SpirngCloud的基礎上進行了二次開發,抽象和封裝了一些微服務架構的通用基礎設施平臺,不同的業務團隊共享這些基礎設施,降低技術學習和接入成本,讓業務團隊更專注於業務邏輯的實現,聚焦業務開發。
3.1 宜信微服務架構
上圖所示為宜信的微服務架構:
- 微服務閘道器,sia-gateway使用了去中心化的閘道器接入方案。
- 元資料服務層,用Eureka-plus和sia-config對註冊中心Eureka和配置中心做了增強與優化。
- 任務管理,基於微服務的思想,開發和開源了微服務任務排程平臺SIA-TASK。
- 容器平臺,實現了快速的自動化構建、部署和服務編排。
- DevOps,微服務的交付頻率、速度比較快,需要有持續整合、持續開發工具和手段來保障專案質量和服務正常執行,對此我們有自研的UAVStack監控系統、自動化測試系統等工具鏈。
3.2 SIA微服務閘道器架構
有別於其他的架構模式,微服務架構裡出現了一個重要的基礎設施變化-增加了微服務閘道器模組。閘道器主要解決的問題是:服務拆分之後,每一個服務粒度都比較小,服務之間的互動會呈現網狀的結構,需要一個聚合的節點來聚合這些微服務。
因此我們在SpringCloud微服務架構的基礎上二次開發出SIA微服務閘道器,如圖所示,重點介紹其中的2個核心模組:
- 閘道器組,閘道器組裡封裝了兩種閘道器:同步閘道器和非同步閘道器。
- OAM,自助式閘道器管理平臺,所有業務節點的生命週期管理都通過這個模組來進行。
3.3 SIA微服務閘道器的4種模式
SIA微服務閘道器的4種模式:同步託管式、同步註解式、非同步託管式、非同步註解式。
1)同步託管式
採用單一原始碼庫進行程式碼管理,交付方式是容器交付,去中心化的設計。目前大部分生產環境和業務都採用同步託管模式。
- 優點:閘道器交付對業務方完全透明;只要在容器平臺申請一個閘道器資源,就可以得到閘道器服務;基於Filter開發運維簡單,容量小。
- 缺點:定製化不夠強。
2)同步註解式
在跟業務團隊對接時,我們發現很多業務系統已經實現了一些獨特的業務邏輯,難以遷移到閘道器,所以我們採用一種比較相容的註解的方式去適應這些業務邏輯,在原有專案的基礎上加一個註解,將它們納入到整個閘道器管理體系中來。同步註解式是基於SpringCloud-Zuul 1實現的分散式微閘道器體系,管理業務方原始碼庫,根據業務方環境進行交付。
- 優點:對專案的控制力比較強,業務團隊獨立運維,支援擴充套件定製化;基於Filter開發運維簡單,容量小。
- 場景:業務定製化場景比較多。如果要載入初始化、加大資源,或對業務的Filter攔截機制有定製化需求,都可以用同步註解模式。
SpringCloud和Zuul使用的後端技術是基於Servlet,其執行緒處理模型是一個請求對應一個執行緒,當請求量過多,執行緒棧溢位,就會佔用非常多的資源,導致閘道器無法提供額外的執行緒資源來處理新進來的請求。因此我們採用了SpringCloud自研的SCG技術方案。
SpringCloud-Gateway基於Netty和反應式程式設計模式,採用收斂式的執行緒處理模型,只要用少數執行緒就可以處理高併發的流量請求。目前已經實現了基於SpringCloud-Gateway的非同步模式,當同步模式在線上執行過程中出現資源透支的情況,就選擇使用非同步模式。非同步模式也分為2種:非同步託管式、非同步註解式。
3)非同步託管式
通過單一原始碼庫進行程式碼管理,採用容器交付。主要使用場景是流量型,如果業務多對高併發、高吞吐場景,建議使用非同步託管式。
4)非同步註解式
如果想在非同步閘道器基礎上做定製開發,可以使用非同步註解的模式。
閘道器的4種模式來源於業務的需求:為相容業務已有邏輯演進出註解模式;當出現效能瓶頸、資源浪費時,採用非同步模式應對高併發流量。
上圖是閘道器測試環境的一個截圖, 包括上述4種模式。每一個小方格代表業務的一個閘道器組,方格中的小圓圈代表它屬於哪一種閘道器。業務系統在選擇閘道器模式時要做一個判斷:訴求是支援業務的快速整合,還是對流量有一定要求。
3.4 SIA微閘道器的核心Feature
如圖將SIA微閘道器的核心Feature分成2個層面:
- 資料面,負責資料包的處理邏輯。路由轉發、負載均衡、灰度釋出、日誌審計、熔斷限流等都是從資料層面對流量進行管理。
- 控制面,負責服務粒度上的管理。統一檢視管理、多租戶管理、註冊中心、配置管理、路由元件繫結等是從控制層面來保障和管理服務。
3.5 SIA微閘道器對微服務的生命週期管理
微服務閘道器貫穿了整個微服務生命週期的管理。
SIA微服務閘道器的功能包括:
- Swagger UI、模組複用對應服務文件中心模組的功能。
- 動態路由、共享能力集中在分散式閘道器節點。
- 日誌管理、管控元件是閘道器Master提供的功能。
各功能模組對應的生命週期:
- 服務文件中心,對應整個軟體生命週期的初期開發和設計階段,閘道器提供一個個統一的API檢視,前端和後臺可以通過Swagger UI來聯調開發。
- 分散式閘道器節點,在開發和部署階段會涉及到一些共享能力的部署和執行。
- 閘道器Master,在運維階段通過自動化運維提高運維效率;在管理方面,提供資料統計的功能,生成資料報告用於管控。
SIA微服務閘道器作用於軟體生命週期的各個階段,通過標準協同、業務測試/前端後端溝通、服務模組複用、視覺化管理、資料統計管控等實現業務的統一融合、降本增效。
3.6 總結:微服務架構與中臺&後臺
2016年,Gartner 釋出了一個關於應用變化速率的報告《Pace-Layered Application Strategy》,以應用變化速率為標準將業務應用分為三層:
- SOI-敏態業務:比如網際網路業務,需求變更快,要求快速迭代 、快速交付。
- SOR-穩態業務: 比如傳統業務,變更週期⻓、變化頻率低、變化成本高、變化⻛險高。
- SOD-中臺業務: 齒輪匹配失衡,中臺就像是在前臺與後臺之間新增的⼀組“變速⻮輪”,將前臺與後臺的速率進行匹配,提升⽤戶響應力。
中臺的目標是圍繞業務組織進行可複用能力的有機整合,協助業務落地實施、改造、試錯、轉型,提升組織效率,降低系統成本。
中臺和微服務有什麼關係呢?微服務架構是面向開發的架構,很多基礎服務可以沉澱到微服務架構裡,同時,微服務架構把中臺的能力快速釋放出來,滿足敏態業務快速變更的業務需求。
四、應用場景及典例分析
4.1 分解&聚合
上圖是路由管理裡的一個截圖,當一個大的單體或不同的服務要對外提供統一服務時,可以把服務聚合到閘道器上;同時一個巨型應用也可以通過閘道器分解成微服務。
4.2 複用&個性化
微服務架構中有很多非功能需求,或者說是技術導向型的需求,包括日誌管理、限流、藍綠部署、版本管理等,可以通過元件的方式下沉到閘道器上,業務系統通過將服務與元件繫結實現對元件功能的複用。
我們還提供了一個外掛機制,當業務有獨特的需求,可以根據其業務邏輯在閘道器上進行功能的個性化定製。
4.3 API&契約
在開發或前後端聯調時,前後端可以通過閘道器服務文件中心的Swagger UI功能模組訪問後端服務呼叫介面的分析。
只要在後端服務之上加一個Swagger註解,閘道器就可以把所有對外暴露的服務抓取出來,這相當於是一種契約式的開發。
4.4 容錯&保護
我們對閘道器應用做了容錯和保護機制,當然這也是SpringCloud本身自帶的一個技術模組,我們的容錯機制是基於SpringCloud的Hystrix實現的,當發現後端服務呼叫請求一直在返回錯誤時,會開啟熔斷,避免由於一直髮送錯誤請求導致雪崩的情況發生。
除此之外,我們還會採用Guava限流的方式對服務進行保護。在大促或秒殺的場景下,會有大量請求進來,這時會通過限流來保護服務的穩定。
4.5 監控&治理
宜信微服務架構平臺有一個很重要的功能是閘道器服務執行狀態和後端連線狀態可觀測,提供了很多監控方面的功能元件,如圖所示,可以統計當前請求的頻率、服務健康度。
預警方面重點介紹閘道器拓撲圖。當請求失敗,當前鏈路出現異常,通過閘道器拓撲圖可以快速跟蹤和判斷業務系統哪個節點出現問題,然後對有問題的節點進行摘除或其他操作。
我們的閘道器執行在Docker平臺上,Docker平臺在出現問題或重啟之後日誌會丟失,我們的日誌系統會把日誌歸集,儲存到ES中,便於對歷史日誌溯源。
4.6 統計&分析
閘道器中有一個元件叫“監控統計”,這個模組預設是不開啟的,如果你想對請求做延時,或者想看請求的明細呼叫情況,可以通過元件管理中開啟這個元件,對容器的請求做統計和分析。監控統計元件會對當前請求的最大延遲、最小延遲、失敗個數、平均延遲進行排序,一目瞭然。
五、微服務化架構建設遇到的問題
5.1 設計初期的問題
1)如何隔離業務閘道器,同時有統一的管理檢視?
構建微服務閘道器初期,業務同事比較關注我們的業務閘道器和別人的閘道器是否存在耦合問題,他的業務請求是否會影響到我。我們選用去中心的閘道器設計方式,同時通過OAM實現對所有閘道器節點的統一管理。
2)平臺型系統建設初期是否要考慮同步非同步閘道器融合?
我們的微服務閘道器是按照DDD領域驅動模式來建設的,沒有把閘道器繫結在某一個特殊的技術實現上,而是把它作為一個抽象封裝來統一管理後端的節點,如果換一種技術實現也不會影響到前端業務的正常工作。因此在架構建設初期要考慮清楚你的業務系統和後端技術架構之間是否解耦。
5.2 使用開源方案的問題
3)開源系統本身的bug
雖然每一種開源方案在開源之前都經過了長時間的考驗,但其實依然可能存在bug,基於這些開源方案進行二次開發時仍可能遇到一些坑,我們會不斷對開源系統進行bug修復和功能增強。
4)系統的效能問題
Zuul本身存在效能瓶頸,當出現效能問題時,我們考慮是不是要用執行緒收斂的模式來增強閘道器的效能。
5.3 上線生產運維方面的問題
5)如何克服Eureka註冊中心的CAP問題?
在閘道器應用中會遇到Eureka的CAP問題,因為Eureka訊息註冊以可用性(Availability)優先,在一致性(Consistency)上相對較弱。為解決這個問題,我們基於Eureka的特點提供SynchSpeed服務,如果業務需要保證狀態一致性,可以開啟這個服務。
6)SpringCloud與SpirngBoot不同版本的相容問題? K8S平臺與微服務註冊中心狀態同步?
這兩個問題是指當雲容器平臺的狀態發生變更,卻沒有及時通知到註冊中心,導致服務在兩個平臺的狀態不一致,這就需要做上下文關聯絡統(StakeHolder)的整合。
內容來源:宜信技術學院第8期技術沙龍-線上直播|宜信微服務架構落地及其演進
主講人:宜信高階架構師 & 宜信科技中心基礎研發部SIA微服務閘道器負責人王佩華