支持 gRPC 長連接,深度解讀 Nacos 2.0 架構設計及新模型

做者

本名楊翊,花名席翁。Nacos PMC,主要參與的是服務發現模塊,和作一些內核重構和提高的工做。 Apache SharadingSphere PMC,主要負責和參與過的模塊有 路由模塊、分佈式事務、 數據同步、以及彈性擴容。python

Nacos 簡介

Nacos 在阿里巴巴起源於 2008 年五彩石項目,該項目完成了微服務拆分和業務中臺建設,隨着雲計算和開源環境的興起,2018 年咱們深入感覺到開源軟件行業的影響,所以決定將 Nacos 開源,輸出阿里十年關於服務發現和配管管理的沉澱,推進微服務行業發展,加速企業數字化轉型。git

目前Nacos支持主流微服務開發語言&主流服務框架和配置管理框架,好比支持Duboo和SCA, 還對接了一些雲原生的組件好比coreDNS和sentinel等。github

客戶端語言方面支持諸如Java,go python等主流語言,還有近期剛發佈正式版本的C#和C++,在此感謝全部社區貢獻者的支持。 spring

Nacos 開源2年多以來,共發佈了34個版本,其中有一些比較重要的里程碑版本;Nacos還很是年輕,有很大的進步空間,歡迎社區及各界大佬一塊兒共同建設。 數據庫

Nacos 1.X架構及問題

接下來咱們看一下nacos1.x架構及其分析一下存在的比較重要的問題。 首先先來看一下架構簡圖。緩存

Nacos 1.X架構層次

Nacos 1.X 大體分爲5層, 分別是接入、通訊、功能、同步和持久化。網絡

接入層是用戶最直接交互的層面,主要有Nacos客戶端,以及依賴客戶端的Dubbo和SCA以及用戶操做的控制檯Console組成。 客戶端和Console進行服務和配置操做,統一經過HTTP的OpenAPI發起通訊請求。數據結構

通訊層主要基於HTTP的短鏈接請求模型進行,部分推送功能經過UDP進行通訊。架構

功能目前有服務發現和配置管理,這層也就是實際管理服務和配置的業務層。負載均衡

同步層有數據同步的AP模式Distro和CP模式Raft,還有有一個最簡易的水平通知Notify,用處各不相同:

  • Distro:非持久化服務的同步模式
  • Raft:持久化服務的同步模式、以及使用Derby做爲配置的存儲時同步配置操做。
  • Notify:使用MySQL做爲配置的存儲時,通知其餘節點更新緩存及發起配置推送。

持久化層Nacos使用MySQL、Derby和本地文件系統來進行數據的持久化 配置信息,用戶信息,權限信息存儲在MySQL或Derby數據庫中, 持久化服務信息及服務和實例元數據信息存儲在本地文件系統。

Nacos 1.X架構下的服務模型

咱們經過一個服務發現的流程,再深刻熟悉一下Nacos 1.X架構和基於當前架構的Nacos服務發現模型。

Nacos客戶端註冊服務會經過OpenAPI發送Http註冊服務的請求,請求內容會帶上服務信息及實例信息,一般這個步驟是由微服務框架SCA和dubbo完成。

服務端收到請求後,會先在Contoller中進行數據的讀取和校驗,好比IP是否合法,服務名是否正確等等。校驗經過後,若是這個服務是第一次註冊,Nacos會在服務端生成一個Service對象,而後把此次註冊的實例信息存入這個Service對象中;若是Nacos服務端已經有了這個Service對象,那麼就會直接把新註冊的實例信息存入對象。這個Service對象經過 命名空間+Group+Service 的組合來保證惟一性。

完成實例存入Service的同時,會觸發兩個事件,其中一個事件是用於數據同步的,Nacos服務端會根據這個服務是不是臨時對象的信息,使用Distro或者Raft協議進行同步,通知其餘的Nacos節點該服務發生了變動;另外一個事件則通知在該Nacos服務節點上訂閱了該服務的訂閱者,並根據訂閱者信息,經過UDP的方式,把最新的服務列表推送到訂閱者客戶端上。這就完成了一次服務註冊流程。

另外,對於那些被定義爲持久化的服務的全部信息,都會經過raft協議,保證可以寫入到文件系統中被持久化。

最後,其餘的Nacos節點,在經過同步而進行Service變動的時候也會觸發通知訂閱者的事件,從而使在其餘Nacos服務節點上訂閱該服務的訂閱者也能收到推送。

1.X架構存在的問題

粗略介紹了下 Nacos1.X的架構和服務發現模型,接下來分析一下Nacos1.X架構所面臨的幾個比較重要的問題。

一句話總結,心跳多,無效查詢多,心跳續約感知變化慢,鏈接消耗大,資源空耗嚴重。

一、 心跳數量多,致使TPS居高不下

經過心跳續約,當服務規模上升時,特別是相似Dubbo的接口級服務較多時,心跳及配置元數據的輪詢數量衆多,致使集羣TPS很高,系統資源高度空耗。

二、 經過心跳續約感知服務變化,時延長

心跳續約須要達到超時時間纔會移除並通知訂閱者,默認爲15s,時延較長,時效性差。若改短超時時間,當網絡抖動時,會頻繁觸發變動推送,對客戶端服務端都有更大損耗。

三、 UDP推送不可靠,致使QPS居高不下

因爲UDP不可靠,所以客戶端測須要每隔一段時間進行對帳查詢,保證客戶端緩存的服務列表的狀態正確,當訂閱客戶端規模上升時,集羣QPS很高,但大多數服務列表其實不會頻繁改變,形成無效查詢,從而存在資源空耗。

四、基於HTTP短鏈接模型,TIME_WAIT狀態鏈接過多

HTTP短鏈接模型,每次客戶端請求都會建立和銷燬TCP連接,TCP協議銷燬的連接狀態是WAIT_TIME,徹底釋放還須要必定時間,當TPS和QPS較高時,服務端和客戶端可能有大量的WAIT_TIME狀態連接,從而會致使connect time out錯誤或者Cannot assign requested address 的問題。

五、配置模塊的30秒長輪詢 引發的頻繁GC

配置模塊使用HTTP短鏈接阻塞模型來模擬長鏈接通訊,可是因爲並不是真實的長鏈接模型,所以每30秒須要進行一次請求和數據的上下文切換,每一次切換都有引發形成一次內存浪費,從而致使服務端頻繁GC。

Nacos 2.0架構及新模型

Nacos 2.0架構層次

Nacos 2.X 在 1.X的架構基礎上 新增了對長鏈接模型的支持,同時保留對舊客戶端和openAPI的核心功能支持。

通訊層目前經過gRPC和Rsocket實現了長鏈接RPC調用和推送能力。

在服務端測,新增一個連接層,用來將不一樣類型的Request請求,未來自不一樣客戶端的不一樣類型請求,轉化爲相同語意的功能數據結構,複用業務處理邏輯。同時,未來的流量控制和負載均衡等功能也會在連接層處理。

其餘架構分層在大致上保持不變。

Nacos 2.0新服務模型

雖然Nacos2.0的在架構層次上並未作太大的變化,可是具體的模型細節卻有不小的改動,依舊使用註冊服務的流程,再深刻了解一下Nacos2.0服務模型的變化。

因爲通訊使用了RPC方式,所以某一客戶端的全部請求(不管是註冊仍是訂閱)都經過同一個連接和同一個服務節點進行,不像以前經過HTTP鏈接可能每次請求都請求在不一樣的Nacos節點上,這就致使了服務發現的數據內容由原來的無狀態化變爲了與鏈接狀態綁定的一種有狀態數據。爲了適應這種變化,須要改變一下數據模型,所以抽象了一個新數據結構,將同一個客戶端經過該連接發佈和訂閱的內容關聯起來,暫命名爲Client。這個Client不是客戶端的意思,而是這個客戶端所相關的數據內容,一個連接與一個Client對應。

當客戶端發佈了服務時,該客戶端所發佈的全部服務與訂閱者信息會被更新到與該客戶端連接相對應的Client對象中,而後經過事件機制觸發對索引信息的更新。這個索引信息是客戶端連接和服務的索引,方便快速聚合生成須要推送的服務緯度的數據。

索引信息更新完成後,會觸發推送事件,此時會將全部和該服務有關的Client對象,經過剛產生的索引信息聚合起來,當數據聚合完成後,再從客戶端連接中篩選出訂閱該服務的訂閱者的客戶端連接,將推送數據經過該連接,推送回去。這樣一次發佈變動的主鏈路就完成了。

回過頭看數據同步,客戶端發佈了服務時實際更新的對象從原來的Service變成Client對象,因此須要同步的內容也變成了Client對象;同時服務端間的通訊方式也會換成RPC。這裏只有真正被客戶端更新的Client對象會觸發同步,若是是經過同步而更新的Client對象不會再次觸發同步。

最後看MetadataMetadata是從1.X版本中的Service對象和Instance對象中分離出來的一些屬性:好比服務的元數據label標籤,實例的上下線狀態、權重和元數據label標籤等。這些元數據能夠被openAPI單獨修改,在聚合數據時生效。之因此將元數據拆分出來,區別於基礎數據,緣由是基礎數據,好比:ip端口,服務名等一經發布不該該被修改,並且應當以發佈時的信息爲準;但其餘的原數據,好比上下線狀態和權重,一般是在運行過程當中動態調節的,所以拆分開以後,分爲兩條不一樣的處理工做流應該更加合理。

Nacos 2.0架構的優缺點

前面簡要介紹了Nacos 2.0的架構和新模型的工做方式,接下來咱們分析一下這樣的改動有哪些優缺點。

優勢

一、 客戶端再也不須要定時發送實例心跳,只須要有一個維持鏈接可用keepalive消息便可。重複TPS能夠大幅下降。

二、 TCP鏈接斷開能夠被快速感知到,提高反應速度。

三、 長鏈接的流式推送,比UDP更加可靠;nio的機制具備更高的吞吐量,並且因爲可靠推送,能夠加長客戶端用於對帳服務列表的時間,甚至刪除相關的請求。重複的無效QPS能夠大幅下降。

四、 長鏈接避免頻繁鏈接開銷,能夠大幅緩解TIME_ WAIT問題。

五、 真實的長鏈接,解決配置模塊GC問題。

六、 更細粒度的同步內容,減小服務節點間的通訊壓力。

缺點

沒有銀彈的方案,新架構也會引入一些新問題

一、 內部結構複雜度上升,管理鏈接狀態,鏈接的負載均衡須要管理。

二、 數據又原來的無狀態,變爲與鏈接綁定的有狀態數據,流程鏈路更長。

三、 RPC協議的觀測性不如HTTP。即便gRPC基於HTTP2.0Stream實現,仍然不如直接使用HTTP協議來的直觀。

Nacos 2.X 規劃

簡單分享下Nacos 2.X 的後期規劃吧。主要分爲文檔、質量和Roadmap。

在文檔和質量方面,Nacos 1.X都作的不是很好。文檔內容較少,僅有簡單使用文檔;和版本有必定脫節,更新不及時;沒有對技術內容的說明,參與貢獻難度高。代碼質量及測試質量也不是很高,雖然已經使用checkstyle進行了codeStyle的校驗以及開啓了社區協做review。可是這還遠遠不夠。Nacos 2.X將會逐步更新、細化官網使用文檔;經過電子書對技術細節進行解析;經過Github展現技術方案,促進討論及貢獻;而且對代碼進行大量重構及UT和IT的治理工做,在將來將Benchmark也會開源出來,方便給開源用戶進行壓測。

而RoadMap方面, Nacos 2.X 會對項目作大幅度的重構,完成初步插件化,並對剛纔2.0架構的一些缺點,如負載均衡,可觀測性進行提高。

加入咱們

歡迎在 Nacos github 上提交issue與PR進行討論和貢獻。或加入Nacos社區羣參與社區討論。

除了參與開源,咱們也歡迎更多有能力及有意願的同窗加入阿里雲共建雲原生,詳情請看雲原生應用平臺

本文整理自Spring Cloud Alibaba Meetup杭州站演講,整年Spring Cloud Alibaba Meetup整年規劃戳這裏

相關文章
相關標籤/搜索