近萬服務實例穩定運行 0 故障,攜程微服務架構是如何落地的?

攜程從 .Net 技術棧的時代就已經開始微服務領域的探索,轉入 Java  技術棧以後,更是經歷了自研微服務框架,到如今高性能的 dubbo,目前咱們正在 Service Mesh 的道路上探索,但願可以實現微服務框架的全面標準化、以及雲原生。git

過去(自研服務框架)

攜程從 .Net 技術棧開始,最開始是基於 ESB 總線,雖然解決了內網服務調用的治理問題,可是集中式的服務架構,常常會出現單個服務把整個總線拖垮的狀況,進而致使全網癱瘓的現象。基於註冊中心的 SOA 服務架構,經過分佈式的服務調用,解決了單點故障帶來的巨大影響。目前,攜程主要是以 技術棧爲主,考慮到兼容歷史 .Net 技術棧,因此如今的框架以自研爲主,可是對比開源的高性能服務框架,自研的框架可能又存在下述提到的幾個問題。github

如今(CDubbo 服務框架)

CDubbo 名字裏的 C 表明攜程的治理,Dubbo 表明阿里開源的 Dubbo SDK。縱觀過去兩年的實踐和探索,從 2018 年 4 月的第一個版本落地,到如今的近萬服務實例,咱們大體能夠總結爲下面的幾個主要里程碑。數據庫

一、註冊發現架構

註冊發現是分佈式服務框架的核心要素,爲了支持現有的服務互通,因此須要接入攜程的註冊中心。負載均衡

服務註冊支持健康檢測擴展機制,業務能夠根據業務場景自定義健康檢測擴展,例如當依賴的數據庫不可用時再也不對外提供服務。服務端經過 5s 一次的心跳保持服務的可用性,當連續 N 次沒有發送心跳時就會自動通知客戶端。框架

客戶端發起對服務的訂閱,經過推拉結合的模式,保證節點在客戶端的最終一致性。經過 Dubbo 的擴展機制,實現了自定義的路由策略,好比根據方法名指定路由策略,以及根據請求參數決定不一樣的路由策略,同時也可以支持就近訪問,優先訪問本機房的服務。less

二、監控 - CAT異步

對微服務來講,沒有了監控就比如瞎子同樣,什麼也不清楚。CAT 提供了分佈式鏈路追蹤的能力,能夠提供很好的報表,以及場景化的問題分析。分佈式

有時,須要瞭解服務總的請求量以及單機的請求分佈和 QPS,或者還要知道服務的執行耗時及 99 線。CAT 的聚合報表能夠幫助咱們更好的瞭解服務的健康情況。微服務

對於超時,可能須要知道哪一個階段變慢,客戶端仍是服務端,序列化階段仍是服務執行過程太慢。對於異常報錯,能夠看到哪一個過程出現的異常,同時會打印異常堆棧信息,幫助問題的定位。

三、監控-Metrics

框架人員須要瞭解公司服務的宏觀狀況,好比各機房都有哪些服務,哪些服務使用了 protobuf 序列化格式,哪些服務使用了 SOA 協議等,以及平均執行耗時等狀況。業務同事可能也想知道本身服務具體狀況,好比有哪些調用方,線程池是否已經跑滿了。

經過接入攜程的 Dashboard,能夠提供全局的總量、錯誤量、線程池統計信息,也能夠根據機房、協議、序列化格式等聚合數據。還可以自定義告警規則,在問題發生時可以儘早的介入。

四、動態配置

對業務同事來講,有可能會存在依賴的服務忽然變慢致使客戶端超時的狀況。框架人員可能須要在機房故障時,須要全局調整 check 爲 false,以解決 A B 服務循環依賴誰都沒法啓動的問題。動態配置提供了配置熱生效的能力,不須要爲了一個配置從新發布,成本很高。

服務端的多個方法,可能執行耗時也會有所不一樣,經過多級別的參數配置,能夠設置服務默認超時爲 1s,單獨爲執行較慢的方法設置獨立的超時時間爲 5s。

服務 Owner 可能更清楚本身服務的耗時,經過服務端對客戶端的參數設置,不須要每一個調用方都設置一次超時,設置的時間也會更合理一些。爲了不配置出錯帶來的損失,咱們提供了友好的可視化界面。

五、SOA 協議及互通

爲了支持現有客戶端遷移到 CDubbo,須要考慮支持現有的 SOA 協議。除了要確保兼容 HTTP 1.1 協議不變,其次要保證跟客戶端的序列化器一致。

CDubbo 會經過 Tomcat 端口接收 SOA 協議的請求,利用現有的序列化器執行請求對象的轉換,並保證 Dubbo 內部調用和 Filter 鏈路的一致性,確保業務邏輯的統一,也就是業務代碼不須要改動,就能夠啓動兩個協議。

六、測試平臺

對於私有的二進制協議來講,沒有現成的 Postman 等工具可使用。有時,開發人員須要在本地驗證測試環境的服務,也可能要驗證本地啓動的服務端,每一個開發人員都構造一個客戶端顯得成本比較高。

經過 VI(github 開源叫 coreStone),以及利用 Dubbo 2.7.3 提供的元數據中心和泛化調用能力,咱們實現了相似 postman 的調用工具。不但能夠支持直連,也可以支持本地測試,同時還能夠支持 protobuf 序列化格式。關於 protobuf 序列化的測試方案,已經貢獻到 dubbo 社區,感興趣的同窗能夠自行了解。

七、升級 Dubbo 2.7.3

關於 Dubbo 2.7.3 的詳細升級歷程,能夠參考:https://www.infoq.cn/article/kOxdaV3y9fMZ0Bzs0jb2

如今回顧下升級的最終結果如何。目前,攜程 99% 的服務已經跑在 dubbo 2.7.3 之上,迄今爲止 0 故障,只有一些不兼容的小問題,對於不兼容的問題也是確保了編譯時提早暴露,運行時沒有任何問題。

在發佈後,也陸續的出現了一些小的問題,好比預熱能力不生效,異常狀況下不會回調 onError 等問題,支持服務端異步的 Trace 埋點等,這些問題已經在開源版本完全修復了。

八、Threadless

業務同事反饋,須要把線程控制在理想的範圍以內。可是,dubbo 的線程數量太多,一方面是服務級獨享線程池,當調用方依賴了 10 個服務,每一個服務的 QPS 爲 1,lantency 可能只有 10ms 的狀況下,因爲每一個服務獨立線程池,至少也須要 10 個線程了。若是多服務共享一個線程池,因爲客戶端默認是 Cached 的線程池模式,那麼在這個場景下可能只要 1 個線程就足夠了。另外一方面,對同步服務來講,dubbo 2.7.5 的 threadless 能夠省去 DubboClientHandler 線程,Netty IO 線程直接把響應交給業務線程,從而節省了一次線程切換。

經過實踐,業務線程數量有了很大程度的降低,在高 QPS 以及依賴服務數量較多的狀況下,甚至能夠降低 60-70%。

九、CDubbo 服務體系

現有 CDubbo 的服務體系,同時支持 Dubbo 和 SOA 協議,對於 Dubbo 客戶端可以支持 TCP 協議的傳輸,對於現有的 SOA 客戶端,可以兼容現有的 SOA 協議。

同時,也可以支持內網和外網 gateway 的請求,保證了多協議的配置統一,以及兼容了 SOA 的序列化格式。

十、性能表現

從協議層面來看,Dubbo 協議的響應較 SOA 協議有所提高,平均耗時從以前的 1ms 下降到了 0.3ms 左右,固然具體提高也要根據服務的報文及請求量有所差別。

image

可能有些人會以爲幾毫秒的性能提高不足以掛齒,可是性能的穩定性對服務來講會很重要。咱們觀察了服務流量突增 3-4 倍的狀況下,客戶端還能保持 0 異常。長鏈接的多路複用,提供了很好的抗衝擊能力。

十一、擴展性

微服務框架跟業務代碼耦合比較重,框架人員主要是用 20% 的時間解決業務 80% 的需求,另外 20% 的需求卻須要 80% 時間的問題,更適合留給業務本身去解決,可以提供這個能力的惟有擴展性,dubbo 不管橫向和縱向的擴展能力都很好。

經過實踐,發現業務的確在各個層級都有本身的擴展。例如:業務擴展了 Router 層,支持本身的路由規則,擴展了負載均衡策略,機票同事甚至擴展了 Transport 層換成了適合本身的傳輸協議。

十二、生態

好的生態,能夠下降開發成本,例如利用現有的開源 dubbo admin,dubbo go 等組件。另外,也能夠下降業務的學習成本,在其餘公司學習的 dubbo 框架,到了攜程還能夠接着用,不須要從新學習私有的服務框架。技術支持也比較少,不少業務同事甚至比咱們還熟悉 dubbo 框架。

1三、Dubbo 協議現有問題 & Dubbo 3.0 規劃

除了前面提到的 Dubbo 框架獲得業界普遍承認的優勢,在咱們實踐的過程當中,也發現了現有的 Dubbo 2.x 版本協議存在的一些不足,好比在雲原生大背景下,協議對網關不夠友好,缺少移動端的輕量級 SDK 等。據咱們與 Dubbo 官方維護團隊的深度交流,這些點也都是當前 Dubbo 3.0 在重點突破的方向,以下一代協議、應用級服務發現、雲原生基礎設施支持等,攜程做爲 Dubbo 深度用戶也將持續的參與到 Dubbo 3.0 的建設與落地過程當中。

將來(Service Mesh)

網上關於 Service Mesh 的意義講了不少,衆說紛紜,我的認爲可能最主要仍是如下幾點。

  • 標準化意味着更低的成本,好比研發成本低,學習成本也比較低,其餘公司學習的微服務框架,到攜程還能夠繼續用,省去了學習和踩坑的成本;

  • 進程解耦,框架同窗可能比較感興趣,中間件沒法獨立升級的問題一直困擾着框架研發同窗,在這個問題上,envoy 能夠獨立升級也是值得期待的;

  • 經過下沉,複用了雲基礎設施的一些能力,一方面,可以更好的支持多語言,業務根據本身的場景選擇合適的語言,另外一方面,經過下沉也可以讓 SDK 更簡單,減小Jar依賴的兼容性問題;

  • 由於更加標準以及下沉,可以帶來更好的雲部署能力,業務出海時能夠根據實際狀況部署須要的組件,再也不依賴框架全家桶了。

一、Service Mesh SDK

下圖是 Istio 官網提供的 Service Mesh 架構圖,若是說 Istio 解決了控制平面的標準化,envoy 或者 sofa-mosn 解決了數據平面的標準化,那麼對於 SDK 來講,是否須要有個標準化的組件,或者是否存在適合咱們的標準的 SDK 呢?

對於部分中小公司,沒有本身的中間件團隊,可能會選擇商業版 SDK。可是,對於攜程這樣的規模,對擴展性要求很強,同時已經存在上千 dubbo 服務的公司來講,咱們可能更期待 3.0 的標準協議。

二、現有協議不適合下沉

現有的 SOA 協議可能不太適合做爲標準協議,基於 Http 1.1 的文本協議,跟 TCP 協議相比,建連帶來的成本,很大程度上會致使長尾,影響服務的穩定性。

Dubbo 協議因爲對網關不太友好,同時存在着跨語言和協議穿透性等問題,envoy 自己也能夠理解爲單機網關代理,因此也不太適合做爲標準協議。

其次,存在的跨語言和協議穿透性問題,阿里劉軍同窗有過度享,感興趣的同窗能夠參考:https://www.infoq.cn/article/y5HC2JjtAvMWYILmVILU

三、新協議

既然現有的協議都不太適合,是否能夠考慮雲原生的標準協議 gRPC。沒錯,從協議層面來看,這個選擇沒有問題,可是 gRPC 跟 proto 強綁定的問題,須要攜程現有的幾千個服務重寫業務邏輯代碼,這個成本但是沒法被接受的。

咱們對於新的協議的期待,應該是可以基於 POJO 對象,同時還要符合 gRPC 協議規範。一方面,可以很好的利用雲原生的基礎能力。另外一方面,對於小衆語言,也能夠利用現有的 gRPC 框架實現與主流 SDK 的互通。

對於新的 SDK,不但要有標準的傳輸協議,同時考慮到服務框架與業務的緊密耦合,擴展性也是要保留的主要的特性,還須要考慮 API 的標準化,利用統一的監控組件。

四、總結

如今,咱們實現了 SDK 的部分標準化。將來,咱們必定會在雲原生的道路上走的更快,更穩,更標準。

做者 | 顧海洋 來源 | 阿里巴巴雲原生(ID:Alicloudnative)

相關文章
相關標籤/搜索