貨拉拉應用架構演進,堪稱單體落地微服務避坑指南
徐少敏
貨拉拉 技術中心 核心基礎設施部
Java技術專家
- 主要負責貨拉拉Java開發框架、腳手架、任務排程中心、配置中心、SOA和微服務框架的架構設計及框架和工具在貨拉拉技術中心的實施和落地。在網際網路、物聯網、車聯網有多年的應用架構設計與微服務架構轉型的實施落地經驗。
從單體到SOA架構,再從微服務架構到服務網格(Service Mesh)架構,企業應用架構領域每一次技術架構的演進都會給企業帶來更多的價值:職責解耦、能力複用、關注點分離、溝通效率提升、快速演進、快速交付和快速反饋。本次分享主要圍繞應用架構演進以及貨拉拉微服務治理的技術選型等進行思考。
一、應用架構的演進
應用服務架構一直處於不斷演進的過程中,上圖通過對比5種比較主流的架構模式,展示了應用架構的演進歷程和變化。
1、單體架構
在業務發展初期,為了快速落地應用、滿足客戶需求,一般會使用All in One的單體架構。
單體架構的特點是:在每個節點伺服器中,包換應用的全部功能模組程式碼等所有模組都耦合在一個程序裡,系統完全封閉且很複雜,牽一髮動全域性;應用系統很臃腫,維護和版本升級開銷非常大。使用負載均衡分散訪問會話,提高併發處理能力。
單體架構是圍繞web容器打包及部署的架構模式,隨著業務的快速發展,要求實現服務的快速迭代和快速交付,應用架構也演進為以服務為中心的架構模式。
2、RPC架構
RPC架構在現在應用系統的早期還是比較常見的架構模式,就是增加服務層,把冗餘的程式碼和可以複用的業務應用進行拆分提取,封裝成服務。系統架構更加清晰,程式碼質量提高,利於升級和維護,穩定性高。應用層可以更專注於與前端使用者互動。業務處理放在服務層來進行,服務和應用的管理不是自動化,服務層能夠實現HA的功能,適用中小型WEB系統的場景和高併發場景,效能比較好。RPC就是一個典型的RPC架構。
RPC架構也存在一些問題,通過共享分散式物件實現遠端方法呼叫,如果在其中一個物件中新增一個屬性,就會對共享物件的生產者與消費者產生影響,所以RPC架構也是緊耦合的模式。系統互動採用RPC私有TCP協議,服務生產者和消費者存在強程式碼依賴,對異構系統整合不友好。
3、SOA架構
個人認為SOA架構經歷了兩個階段,一是以ESB中心化的架構,二是以註冊服務為中心的服務註冊發現架構(上圖)。
1)ESB中心化架構
ESB中心化架構實現了松耦合,依賴於ESB訊息匯流排技術實現異構系統的資訊互動和整合集中式架構管理,因此它雖然是面向服務的,但它本質上依舊是一箇中心化的架構。
其優勢在於: 基於WebService技術,擁有重量級的訊息通訊機制。當團隊規模比較大、要實現異構系統整合時,它可以提供統一的解決方案和技術實現方式,快速整合異構系統對外服務。
2)以註冊服務為中心的服務註冊發現架構
-
註冊中心負責服務地址的註冊與查詢,相當於目錄服務;
-
服務提供者和消費者只在啟動和訂閱後發生變化時與註冊中心互動,註冊中心不轉發請求,壓力較小;
-
應用層和服務層可以根據需求進行動態水平擴充套件,應用與服務實現負載均衡;
-
通過隨機、輪詢、權重等策略與開放式、標準化的框架,滿足介面呼叫的服務都可以接入服務框架(RPC)監控服務呼叫情況,可進一步對服務層再分層,根據業務需求和服務執行情況對服務進行編排、梳理以及服務治理。
以註冊服務為中心的服務註冊發現架構適用大型及超大型網站應用架構。所以ESB中心化架構的問題也比較明顯:中心化架構難以滿足靈活性的服務迭代和需求交付。
4、微服務架構
微服務架構實現了系統解耦和持續整合,有清晰的服務邊界,相對ESB架構和傳統SOA架構來說粒度更小,使用輕量級的通訊機制(HTTP+REST)互動,具備更強的擴充套件性和彈性,能夠更靈活、更快響應業務變化。
5、服務網格架構
服務網格架構是容器化的產物,引入了類似代理的Sidecar,在微服務SDK裡面保留協議編解碼能力,把服務註冊與發現、負載均衡、熔斷、限流、降級等服務治理能力下沉到Sidecar。當該 sidecar 在微服務中大量部署時,這些 sidecar 節點自然就形成了一個網格。
服務網格架構的優勢: 支援用多語言開發業務、省去或輕量化SDK,為異構服務框架/平臺創造了融合和發展的機會,讓服務框架/平臺的演進更自主、更敏捷,讓業務開發聚焦業務本身,無需關心安全、灰度、熔斷、限流、降級等普遍服務,治理能力更敏捷、更好管控,加速業務探索。
Service Mesh的終局:Mesh所有協議或框架。目前貨拉拉已經實現了Redis Mesh。
通過上述對比,我們不難發現,應用服務架構是在不斷演進的,而且其演進背後存在一定的邏輯,服務架構的演進主要取決於以下2個維度:
-
業務維度, 技術架構是由業務發展所處的時期和階段決定的,要能夠解決業務發展過程中的痛點。在進行架構選型時,需要考慮這個架構是否能滿足當前業務的需求,業務需求能否隨著架構的演進實現增量式的迭代。
-
技術維度, 要滿足非功能需求,使業務快速跟上技術生態的發展。
****綜上所述,應用架構演進的底層邏輯就是: 一切為了敏捷(低投入,快速滿足業務需求)。
二、貨拉拉的All In One Web到微服務治理
貨拉拉應用架構到現在為止經歷了All In One Web的單體架構,RPC架構,與現在的微服務架構。
-
單體架構階段: 2014年釋出的第一個版本就是PHP的All In One Web,一直延續到2016年。
-
RPC架構階段: 從2016年開始,業務量不斷上升,單體架構難以滿足業務需求,從單體應用裡面拆出幾十個dcore,ucore等核心服務。雖然服務之間採用HTTP+REST的呼叫方式,不是RPC的呼叫方式,但這階段和RPC架構一樣,都不具備服務治理能力。
-
微服務階段: 從2020年開始微服務化改造,一直到目前都還處於微服務階段。
1、貨拉拉微服務治理的背景
1)微服務化碰到的問題
從2020年開始微服務化改造,當時階段屬於類似的RPC架構,是基於域名+HTTP的服務互動方式(圖上)。痛點在於:
- 基於域名的管理方式成本非常高: 服務呼叫都還用域名的方式,內部新服務上線都必須申請內部域名,當時已接近500個域名,域名維護成本非常高。
- 協議不統一: PHP和Java服務呼叫、採用HTTP+JSON的協議方式,但業務請求方式不統一,導致研發效率低,插入管理切面異常困難。當時內部業務協議請求方式有GET請求方式、JSON資料以HTTP BODY的POST方式、還有HTTP FORM表單方式。
- 沒服務治理能力: 沒有服務註冊中心,沒有熔斷、降級等保障效能力。服務之間強關聯,呼叫鏈脆弱。若某旁支服務不可用,可能導致整條關鍵鏈路不可用,穩定性無法保證。
- 技術轉型: 公司業務快速發展,大部分業務還是PHP開發,需要向Java轉型或者使用Java來重構。內部500+的應用/服務不能同時轉型或者重構,需逐步推進。
2)微服務化需要解決的問題
- 跨語言: 支援內部PHP和JAVA服務相互呼叫。
- 時間視窗: 開發週期3個月左右。
- 服務治理能力: 具備熔斷、限流、降級等服務治理能力以及全鏈路灰度釋出能力。
- 協議相容要求: 具有泛化呼叫能力(需要類似FeignClient的呼叫方式,相容老的PHP和Java服務)。
- 協議規範要求: 提供標準化RPC的能力。
- 服務註冊發現: 基於APPID的方式,考慮到後續容器化Service Mesh方式的服務治理要求。
2、貨拉拉微服務治理的框架選型
綜合上述需要解決的問題,技術選型和參考的框架:
- SOA架構:Dubbo
- 微服務架構:Spring Cloud
- 服務網格架構:Istio
公司內部基礎設施還未全面容器化,所以服務網格架構方式Istio先淘汰,剩下就是Dubbo和Spring Cloud。我們選型思考的出發點:框架上的缺點或者不足點是不是我們能接受或者克服的。
1)Dubbo2.X的缺點
2020年Dubbo 3.0還未Release,所以我們研究了Dubbo 2.X。
- Dubbo 2.X協議對雲原生支援不友好;
- Dubbo 2.X不支援熔斷、限流、降級等服務治理能力,需要另外的Sentinel等框架支撐;
- Dubbo 3.X Release時間和版本穩定時間未知;
- 很強的RPC契約,沒有泛化呼叫能力,達不到相容老的Java和PHP服務要求;
- Dubbo 2.X基於介面/服務(Inteface/Service)的服務註冊發現方式,對未來Service Mesh方向即基於APPID的服務註冊發現方式支援不友好。
2)Spring Cloud的缺點
- 臃腫、體系過於複雜、不夠輕量,雖然使用門檻低,但深入和改造成本較高;
-
打包的包過大,一般都大於100M,啟動後佔用的記憶體也比較大;
-
服務呼叫協議採用HTTP+REST方式,協議管控能力較弱。
3)自研微服務框架
我們對比後的結論是自研微服務框架,具體微服務體系中元件選型和設計思考如下:
- 標準服務呼叫協議: JSON-RPC(支援Java和PHP服務相互呼叫);
- 註冊中心: Consul;
-
服務治理: 熔斷Hystrix(Hystrix有PHP版本支援);
-
泛化呼叫: 參考FeignClient的客戶端和jsonrpc4j服務定義機制;
-
框架設計: 參考Dubbo的分層機制和優秀設計。
3、貨拉拉微服務治理的實現思路
框架設計參考Dubbo程式碼的分層架構和優秀設計:
- dubbo-common
- dubbo-config
- dubbo-filter
- dubbo-metadata
- dubbo-monitor
- dubbo-registry
- dubbo-remoting
- dubbo-rpc
- dubbo-serialization
- dubbo-springboot
1)泛化呼叫的實現方式
① 參考FeignClient定義介面方式
@FeignClient(value= “XC-SERVICE-MANAGE-CMS”)
其中XC-SERVICE-MANAGE-CMS為下游應用的APPID,FeignClient在Spring Cloud體系中以APPID的方式發現服務。
② 參考jsonrpc4j介面的定義方式
@JsonRpcService("/path/to/MyService")interface MyService {... service methods ...}
③ 泛化呼叫的介面定義方式
④ 標準JSONRPC介面的定義方式
2)服務治理能力整體實現方式
- 熔斷能力: 整合Hystix框架。
- 治理配置: 整合公司內部的配置中心。
- 監控能力: 整合公司內部的監控中心。
- 治理控制檯: 開發治理管控平臺soa-admin。
服務治理管控平臺:soa-admin控制檯
3)Java Agent版本服務治理能力實現方式
- 服務治理能力下沉到Java Agent;
- Java Agent模組化、外掛化,目前外掛有Metric、Trace、SOA;
- Java Agent外掛支援動態升級和灰度升級。
4、貨拉拉微服務治理的未來規劃
未來往Service Mesh演進,但生產落地仍有挑戰。
1)增加的複雜性
在一個已經很複雜的環境中引入代理、sidecar等元件會極大地增加運維的複雜性。
2)需要的專業知識
在容器編排器(如Kubernetes)之上新增Istio之類的服務網格,通常需要運維人員成為這兩種技術的專家。
3)延遲
服務網格是一種入侵的、複雜的技術,它能向服務架構中新增顯著的延遲。
4)平臺的依賴性
服務網格的侵入性迫使開發人員和運維人員適應一個高度自治的平臺,並遵守其規則。
- 貨拉拉移動端Abort異常監控實踐
- 2022|貨拉拉技術團隊精華推薦
- 貨拉拉SSL證書踩坑之旅
- 一種Android應用耗電定位方案
- 貨拉拉應用架構演進,堪稱單體落地微服務避坑指南
- 出行iOS使用者端卡頓治理實踐
- 貨拉拉貨運iOS使用者端架構優化實踐
- 貨拉拉客戶端通用日誌元件 - Glog
- 貨拉拉出行iOS使用者端啟動優化實踐
- 貨拉拉使用者 iOS 端卡頓優化實踐
- 貨拉拉 iOS 包大小優化探索與實踐
- 貨拉拉A/B實驗分流演算法實踐
- 貨拉拉 Android 模組化路由框架:TheRouter
- 貨拉拉iOS司機端執行緒治理總結
- 貨拉拉 Android H5離線包原理與實踐
- 微前端架構的幾種技術選型、從月薪600到進入鵝廠、得物多活架構設計之路由服務設計、 貨拉拉 Android 動態資源管理系統原理 | 醬醬的下午茶第 17 期
- 貨拉拉 Android 動態資源管理系統原理與實踐
- 貨拉拉H5離線包原理與實踐
- 貨拉拉Android穩定性治理
- 貨拉拉Android 包體積優化實踐