php 长连接心跳_支持gRPC长链接,深度解读Nacos2.0架构设计及新模型
作者 | 楊翊(席翁) Nacos PMC
來源|阿里巴巴云原生公眾號(hào)
Nacos 簡(jiǎn)介
Nacos 在阿里巴巴起源于 2008 年五彩石項(xiàng)目,該項(xiàng)目完成了微服務(wù)拆分和業(yè)務(wù)中臺(tái)建設(shè),隨著云計(jì)算和開源環(huán)境的興起,2018 年我們深刻感受到開源軟件行業(yè)的影響,因此決定將 Nacos 開源,輸出阿里十年關(guān)于服務(wù)發(fā)現(xiàn)和配管管理的沉淀,推動(dòng)微服務(wù)行業(yè)發(fā)展,加速企業(yè)數(shù)字化轉(zhuǎn)型。
目前 Nacos 支持主流微服務(wù)開發(fā)語言 & 主流服務(wù)框架和配置管理框架,比如支持 Duboo 和 SCA, 還對(duì)接了一些云原生的組件比如 coreDNS 和 sentinel 等。
客戶端語言方面支持諸如 Java、go python 等主流語言,還有近期剛發(fā)布正式版本的 C# 和 C++,在此感謝所有社區(qū)貢獻(xiàn)者的支持。
Nacos 開源 2 年多以來,共發(fā)布了 34 個(gè)版本,其中有一些比較重要的里程碑版本;Nacos 還非常年輕,有很大的進(jìn)步空間,歡迎社區(qū)及各界大佬一起共同建設(shè)。
Nacos 1.X 架構(gòu)及問題
接下來我們看一下 nacos1.x 架構(gòu)及其分析一下存在的比較重要的問題。首先來看一下架構(gòu)簡(jiǎn)圖。
Nacos 1.X 架構(gòu)層次
Nacos 1.X 大致分為 5 層, 分別是接入、通信、功能、同步和持久化。
接入層是用戶最直接交互的層面,主要有 Nacos 客戶端,以及依賴客戶端的 Dubbo 和 SCA 以及用戶操作的控制臺(tái) Console 組成。客戶端和 Console 進(jìn)行服務(wù)和配置操作,統(tǒng)一通過 HTTP 的 OpenAPI 發(fā)起通信請(qǐng)求。
通信層主要基于 HTTP 的短連接請(qǐng)求模型進(jìn)行,部分推送功能通過 UDP 進(jìn)行通信。
功能目前有服務(wù)發(fā)現(xiàn)和配置管理,這層也就是實(shí)際管理服務(wù)和配置的業(yè)務(wù)層。
同步層有數(shù)據(jù)同步的 AP 模式 Distro 和 CP 模式 Raft,還有有一個(gè)最簡(jiǎn)易的水平通知 Notify,用處各不相同:
- Distro:非持久化服務(wù)的同步模式。
- Raft:持久化服務(wù)的同步模式、以及使用 Derby 作為配置的存儲(chǔ)時(shí)同步配置操作。
- Notify:使用 MySQL 作為配置的存儲(chǔ)時(shí),通知其他節(jié)點(diǎn)更新緩存及發(fā)起配置推送。
持久化層 Nacos 使用 MySQL、Derby 和本地文件系統(tǒng)來進(jìn)行數(shù)據(jù)的持久化 配置信息,用戶信息,權(quán)限信息存儲(chǔ)在 MySQL 或 Derby 數(shù)據(jù)庫中, 持久化服務(wù)信息及服務(wù)和實(shí)例元數(shù)據(jù)信息存儲(chǔ)在本地文件系統(tǒng)。
Nacos 1.X 架構(gòu)下的服務(wù)模型
我們通過一個(gè)服務(wù)發(fā)現(xiàn)的流程,再深入熟悉一下 Nacos 1.X 架構(gòu)和基于當(dāng)前架構(gòu)的 Nacos 服務(wù)發(fā)現(xiàn)模型。
Nacos 客戶端注冊(cè)服務(wù)會(huì)通過 OpenAPI 發(fā)送 Http 注冊(cè)服務(wù)的請(qǐng)求,請(qǐng)求內(nèi)容會(huì)帶上服務(wù)信息及實(shí)例信息,通常這個(gè)步驟是由微服務(wù)框架 SCA 和 dubbo 完成。
服務(wù)端收到請(qǐng)求后,會(huì)先在 Contoller 中進(jìn)行數(shù)據(jù)的讀取和校驗(yàn),比如 IP 是否合法,服務(wù)名是否正確等等。校驗(yàn)通過后,如果這個(gè)服務(wù)是第一次注冊(cè),Nacos 會(huì)在服務(wù)端生成一個(gè) Service 對(duì)象,然后把這次注冊(cè)的實(shí)例信息存入這個(gè) Service 對(duì)象中;如果 Nacos 服務(wù)端已經(jīng)有了這個(gè) Service 對(duì)象,那么就會(huì)直接把新注冊(cè)的實(shí)例信息存入對(duì)象。這個(gè) Service 對(duì)象通過 命名空間+Group+Service 的組合來保證唯一性。
完成實(shí)例存入 Service 的同時(shí),會(huì)觸發(fā)兩個(gè)事件,其中一個(gè)事件是用于數(shù)據(jù)同步的,Nacos 服務(wù)端會(huì)根據(jù)這個(gè)服務(wù)是否是臨時(shí)對(duì)象的信息,使用 Distro 或者 Raft 協(xié)議進(jìn)行同步,通知其他的 Nacos 節(jié)點(diǎn)該服務(wù)發(fā)生了變更;另一個(gè)事件則通知在該 Nacos 服務(wù)節(jié)點(diǎn)上訂閱了該服務(wù)的訂閱者,并根據(jù)訂閱者信息,通過 UDP 的方式,把最新的服務(wù)列表推送到訂閱者客戶端上。這就完成了一次服務(wù)注冊(cè)流程。
另外,對(duì)于那些被定義為持久化的服務(wù)的所有信息,都會(huì)通過 raft 協(xié)議,保證能夠?qū)懭氲轿募到y(tǒng)中被持久化。
最后,其他的 Nacos 節(jié)點(diǎn),在通過同步而進(jìn)行 Service 變更的時(shí)候也會(huì)觸發(fā)通知訂閱者的事件,從而使在其他 Nacos 服務(wù)節(jié)點(diǎn)上訂閱該服務(wù)的訂閱者也能收到推送。
1.X 架構(gòu)存在的問題
粗略介紹了下 Nacos1.X 的架構(gòu)和服務(wù)發(fā)現(xiàn)模型,接下來分析一下 Nacos1.X 架構(gòu)所面臨的幾個(gè)比較重要的問題。
一句話總結(jié),心跳多,無效查詢多,心跳續(xù)約感知變化慢,連接消耗大,資源空耗嚴(yán)重。
- 心跳數(shù)量多,導(dǎo)致 TPS 居高不下
通過心跳續(xù)約,當(dāng)服務(wù)規(guī)模上升時(shí),特別是類似 Dubbo 的接口級(jí)服務(wù)較多時(shí),心跳及配置元數(shù)據(jù)的輪詢數(shù)量眾多,導(dǎo)致集群 TPS 很高,系統(tǒng)資源高度空耗。
- 通過心跳續(xù)約感知服務(wù)變化,時(shí)延長(zhǎng)
心跳續(xù)約需要達(dá)到超時(shí)時(shí)間才會(huì)移除并通知訂閱者,默認(rèn)為 15s,時(shí)延較長(zhǎng),時(shí)效性差。若改短超時(shí)時(shí)間,當(dāng)網(wǎng)絡(luò)抖動(dòng)時(shí),會(huì)頻繁觸發(fā)變更推送,對(duì)客戶端服務(wù)端都有更大損耗。
- UDP 推送不可靠,導(dǎo)致 QPS 居高不下
由于 UDP 不可靠,因此客戶端測(cè)需要每隔一段時(shí)間進(jìn)行對(duì)賬查詢,保證客戶端緩存的服務(wù)列表的狀態(tài)正確,當(dāng)訂閱客戶端規(guī)模上升時(shí),集群 QPS 很高,但大多數(shù)服務(wù)列表其實(shí)不會(huì)頻繁改變,造成無效查詢,從而存在資源空耗。
- 基于 HTTP 短連接模型,TIME_WAIT 狀態(tài)連接過多
HTTP 短連接模型,每次客戶端請(qǐng)求都會(huì)創(chuàng)建和銷毀 TCP 鏈接,TCP 協(xié)議銷毀的鏈接狀態(tài)是 WAIT_TIME,完全釋放還需要一定時(shí)間,當(dāng) TPS 和 QPS 較高時(shí),服務(wù)端和客戶端可能有大量的 WAIT_TIME 狀態(tài)鏈接,從而會(huì)導(dǎo)致 connect time out 錯(cuò)誤或者 Cannot assign requested address 的問題。
- 配置模塊的 30 秒長(zhǎng)輪詢引起的頻繁 GC
配置模塊使用 HTTP 短連接阻塞模型來模擬長(zhǎng)連接通信,但是由于并非真實(shí)的長(zhǎng)連接模型,因此每 30 秒需要進(jìn)行一次請(qǐng)求和數(shù)據(jù)的上下文切換,每一次切換都有引起造成一次內(nèi)存浪費(fèi),從而導(dǎo)致服務(wù)端頻繁 GC。
Nacos 2.0 架構(gòu)及新模型
Nacos 2.0 架構(gòu)層次
Nacos 2.X 在 1.X 的架構(gòu)基礎(chǔ)上 新增了對(duì)長(zhǎng)連接模型的支持,同時(shí)保留對(duì)舊客戶端和 openAPI 的核心功能支持。
通信層目前通過 gRPC 和 Rsocket 實(shí)現(xiàn)了長(zhǎng)連接 RPC 調(diào)用和推送能力。
在服務(wù)端測(cè),新增一個(gè)鏈接層,用來將不同類型的 Request 請(qǐng)求,將來自不同客戶端的不同類型請(qǐng)求,轉(zhuǎn)化為相同語意的功能數(shù)據(jù)結(jié)構(gòu),復(fù)用業(yè)務(wù)處理邏輯。同時(shí),將來的流量控制和負(fù)載均衡等功能也會(huì)在鏈接層處理。
其他架構(gòu)分層在大體上保持不變。
Nacos 2.0 新服務(wù)模型
雖然 Nacos2.0 的在架構(gòu)層次上并未做太大的變化,但是具體的模型細(xì)節(jié)卻有不小的改動(dòng),依舊使用注冊(cè)服務(wù)的流程,再深入了解一下 Nacos2.0 服務(wù)模型的變化。
由于通信使用了 RPC 方式,因此某一客戶端的所有請(qǐng)求(無論是注冊(cè)還是訂閱)都通過同一個(gè)鏈接和同一個(gè)服務(wù)節(jié)點(diǎn)進(jìn)行,不像之前通過 HTTP 連接可能每次請(qǐng)求都請(qǐng)求在不同的 Nacos 節(jié)點(diǎn)上,這就導(dǎo)致了服務(wù)發(fā)現(xiàn)的數(shù)據(jù)內(nèi)容由原來的無狀態(tài)化變?yōu)榱伺c連接狀態(tài)綁定的一種有狀態(tài)數(shù)據(jù)。為了適應(yīng)這種變化,需要改變一下數(shù)據(jù)模型,因此抽象了一個(gè)新數(shù)據(jù)結(jié)構(gòu),將同一個(gè)客戶端通過該鏈接發(fā)布和訂閱的內(nèi)容關(guān)聯(lián)起來,暫命名為 Client。這個(gè) Client 不是客戶端的意思,而是這個(gè)客戶端所相關(guān)的數(shù)據(jù)內(nèi)容,一個(gè)鏈接與一個(gè) Client 對(duì)應(yīng)。
當(dāng)客戶端發(fā)布了服務(wù)時(shí),該客戶端所發(fā)布的所有服務(wù)與訂閱者信息會(huì)被更新到與該客戶端鏈接相對(duì)應(yīng)的 Client 對(duì)象中,然后通過事件機(jī)制觸發(fā)對(duì)索引信息的更新。這個(gè)索引信息是客戶端鏈接和服務(wù)的索引,方便快速聚合生成需要推送的服務(wù)緯度的數(shù)據(jù)。
索引信息更新完成后,會(huì)觸發(fā)推送事件,此時(shí)會(huì)將所有和該服務(wù)有關(guān)的 Client 對(duì)象,通過剛產(chǎn)生的索引信息聚合起來,當(dāng)數(shù)據(jù)聚合完成后,再?gòu)目蛻舳随溄又泻Y選出訂閱該服務(wù)的訂閱者的客戶端鏈接,將推送數(shù)據(jù)通過該鏈接,推送回去。這樣一次發(fā)布變更的主鏈路就完成了。
回過頭看數(shù)據(jù)同步,客戶端發(fā)布了服務(wù)時(shí)實(shí)際更新的對(duì)象從原來的 Service 變成 Client 對(duì)象,所以需要同步的內(nèi)容也變成了 Client 對(duì)象;同時(shí)服務(wù)端間的通信方式也會(huì)換成 RPC。這里只有真正被客戶端更新的 Client 對(duì)象會(huì)觸發(fā)同步,如果是通過同步而更新的 Client 對(duì)象不會(huì)再次觸發(fā)同步。
最后看 Metadata,Metadata 是從 1.X 版本中的 Service 對(duì)象和 Instance 對(duì)象中分離出來的一些屬性:比如服務(wù)的元數(shù)據(jù) label 標(biāo)簽,實(shí)例的上下線狀態(tài)、權(quán)重和元數(shù)據(jù) label 標(biāo)簽等。這些元數(shù)據(jù)可以被 openAPI 單獨(dú)修改,在聚合數(shù)據(jù)時(shí)生效。之所以將元數(shù)據(jù)拆分出來,區(qū)別于基礎(chǔ)數(shù)據(jù),原因是基礎(chǔ)數(shù)據(jù)比如:ip 端口,服務(wù)名等一經(jīng)發(fā)布不應(yīng)該被修改,而且應(yīng)當(dāng)以發(fā)布時(shí)的信息為準(zhǔn);但其他的原數(shù)據(jù),比如上下線狀態(tài)和權(quán)重,通常是在運(yùn)行過程中動(dòng)態(tài)調(diào)節(jié)的,因此拆分開之后,分為兩條不同的處理工作流應(yīng)該更加合理。
Nacos 2.0 架構(gòu)的優(yōu)缺點(diǎn)
前面簡(jiǎn)要介紹了 Nacos 2.0 的架構(gòu)和新模型的工作方式,接下來我們分析一下這樣的改動(dòng)有哪些優(yōu)缺點(diǎn)。
優(yōu)點(diǎn)
- 客戶端不再需要定時(shí)發(fā)送實(shí)例心跳,只需要有一個(gè)維持連接可用 keepalive 消息即可。重復(fù) TPS 可以大幅降低。
- TCP 連接斷開可以被快速感知到,提升反應(yīng)速度。
- 長(zhǎng)連接的流式推送,比 UDP 更加可靠;nio 的機(jī)制具有更高的吞吐量,而且由于可靠推送,可以加長(zhǎng)客戶端用于對(duì)賬服務(wù)列表的時(shí)間,甚至刪除相關(guān)的請(qǐng)求。重復(fù)的無效 QPS 可以大幅降低。
- 長(zhǎng)連接避免頻繁連接開銷,可以大幅緩解 TIME_ WAIT 問題。
- 真實(shí)的長(zhǎng)連接,解決配置模塊 GC 問題。
- 更細(xì)粒度的同步內(nèi)容,減少服務(wù)節(jié)點(diǎn)間的通信壓力。
缺點(diǎn)
沒有銀彈的方案,新架構(gòu)也會(huì)引入一些新問題:
- 內(nèi)部結(jié)構(gòu)復(fù)雜度上升,管理連接狀態(tài),連接的負(fù)載均衡需要管理。
- 數(shù)據(jù)又原來的無狀態(tài),變?yōu)榕c連接綁定的有狀態(tài)數(shù)據(jù),流程鏈路更長(zhǎng)。
- RPC 協(xié)議的觀測(cè)性不如 HTTP。即使 gRPC 基于 HTTP2.0Stream 實(shí)現(xiàn),仍然不如直接使用 HTTP 協(xié)議來的直觀。
Nacos 2.X 規(guī)劃
接下來簡(jiǎn)單分享下 Nacos 2.X 的后期規(guī)劃,主要分為文檔、質(zhì)量和 Roadmap。
在文檔和質(zhì)量方面,Nacos 1.X 都做的不是很好。文檔內(nèi)容較少,僅有簡(jiǎn)單使用文檔;和版本有一定脫節(jié),更新不及時(shí);沒有對(duì)技術(shù)內(nèi)容的說明,參與貢獻(xiàn)難度高。代碼質(zhì)量及測(cè)試質(zhì)量也不是很高,雖然已經(jīng)使用 checkstyle 進(jìn)行了 codeStyle 的校驗(yàn)以及開啟了社區(qū)協(xié)作 review。但是這還遠(yuǎn)遠(yuǎn)不夠。Nacos 2.X 將會(huì)逐步更新、細(xì)化官網(wǎng)使用文檔;通過電子書對(duì)技術(shù)細(xì)節(jié)進(jìn)行解析;通過 Github 展示技術(shù)方案,促進(jìn)討論及貢獻(xiàn);并且對(duì)代碼進(jìn)行大量重構(gòu)及 UT 和 IT 的治理工作,在未來將 Benchmark 也會(huì)開源出來,方便給開源用戶進(jìn)行壓測(cè)。
而 RoadMap 方面,Nacos 2.X 會(huì)對(duì)項(xiàng)目做大幅度的重構(gòu),完成初步插件化,并對(duì)剛才 2.0 架構(gòu)的一些缺點(diǎn),如負(fù)載均衡,可觀測(cè)性進(jìn)行提升。
作者簡(jiǎn)介
楊翊,花名席翁。Nacos PMC,主要參與的是服務(wù)發(fā)現(xiàn)模塊,和做一些內(nèi)核重構(gòu)和提升的工作。Apache SharadingSphere PMC,主要負(fù)責(zé)和參與過的模塊有 路由模塊、分布式事務(wù)、 數(shù)據(jù)同步、以及彈性擴(kuò)容。
總結(jié)
以上是生活随笔為你收集整理的php 长连接心跳_支持gRPC长链接,深度解读Nacos2.0架构设计及新模型的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 卡片使用_APP必备的设计元素!卡片
- 下一篇: 上海欢乐谷烘干要钱吗