五分鐘技術(shù)趣談 | 淺析Nacos注冊(cè)中心
Part 01
單體架構(gòu)到微服務(wù)
在web程序發(fā)展的早期,功能模塊都是被打包成單體應(yīng)用,在一個(gè)web容器中運(yùn)行,這個(gè)應(yīng)用通常包含后端的所有模塊和前端,后端所有功能模塊訪問同一個(gè)數(shù)據(jù)庫。這樣的好處是開發(fā)效率高、易部署、易測(cè)試等。
圖1 單體架構(gòu)
但隨著大規(guī)模的復(fù)雜應(yīng)用出現(xiàn),單體應(yīng)用展現(xiàn)出了很多不足,包括:可維護(hù)性變差、版本迭代速度變慢、可擴(kuò)展能力差等。
微服務(wù)架構(gòu)的出現(xiàn),解決了上述問題,微服務(wù)架構(gòu)與單體應(yīng)用的區(qū)別是,微服務(wù)架構(gòu)是將一個(gè)龐大復(fù)雜的應(yīng)用分解為多個(gè)小的互相鏈接的微服務(wù),一個(gè)微服務(wù)一般只完成一類相關(guān)功能,比如:商品、訂單,每個(gè)服務(wù)可能有自己獨(dú)立的數(shù)據(jù)庫。
圖2 微服務(wù)架構(gòu)
Part 02
注冊(cè)中心的演變
在微服務(wù)架構(gòu)中,不同服務(wù)間免不了要相互通信,這就需要對(duì)這些服務(wù)信息進(jìn)行管理,主要包括:服務(wù)的生產(chǎn)方、服務(wù)的消費(fèi)方,服務(wù)方的物理位置等。如果微服務(wù)是部署在固定的機(jī)器上的,直接通過代碼就可以進(jìn)行服務(wù)間調(diào)用,但實(shí)際情況是微服務(wù)可能部署在云環(huán)境,服務(wù)實(shí)例的網(wǎng)絡(luò)位置是動(dòng)態(tài)分配的;此外根據(jù)實(shí)際負(fù)載情況部署節(jié)點(diǎn)也會(huì)動(dòng)態(tài)調(diào)整,基于以上問題就需要一個(gè)服務(wù)管理工具,幫助我們實(shí)現(xiàn)服務(wù)的動(dòng)態(tài)管理。
對(duì)于小體量的微服務(wù),早期Nginx 就可以滿足服務(wù)管理的需求,具體是通過Nginx維護(hù)服務(wù)列表(upStream)實(shí)現(xiàn)。但隨著微服務(wù)數(shù)量的增多,吞吐量下降會(huì)很嚴(yán)重,Nginx配置文件維護(hù)起來也更加困難。
這時(shí)出現(xiàn)了注冊(cè)中心,微服務(wù)先注冊(cè)到注冊(cè)中心,如果服務(wù)1想調(diào)用服務(wù)2,需要先到服務(wù)中心去獲取相應(yīng)接口,然后再去調(diào)用服務(wù)2,這樣就解決了上邊動(dòng)態(tài)網(wǎng)絡(luò)位置的問題,最簡(jiǎn)單的Nacos注冊(cè)中心如下所示:
圖3 Nacos注冊(cè)中心
Part 03
Nacos的服務(wù)發(fā)現(xiàn)
那么Nacos協(xié)調(diào)服務(wù)之間的調(diào)用細(xì)節(jié)是怎樣的呢?首先服務(wù)需要注冊(cè),注冊(cè)的目的就是將服務(wù)ip、端口等信息上報(bào)給Nacos注冊(cè)中心;然后是服務(wù)訂閱,訂閱和退訂的目的是方便動(dòng)態(tài)管理需要相互通信的服務(wù),實(shí)現(xiàn)高效交互;最后是服務(wù)調(diào)用,至此完成了一個(gè)具體功能,具體實(shí)現(xiàn)過程如下:
1、每個(gè)服務(wù)啟動(dòng)后會(huì)向Nacos注冊(cè)中心上報(bào)自己的網(wǎng)絡(luò)地址,服務(wù)和Nacos間通過grpc協(xié)議進(jìn)行通信,Nacos通過域名解析出服務(wù)端ip列表,這個(gè)ip列表就是服務(wù)網(wǎng)絡(luò)地址的數(shù)據(jù)庫,Nacos會(huì)選擇其中一個(gè)ip創(chuàng)建 grpc 連接,并定時(shí)檢查連接狀態(tài),當(dāng)連接斷開,則自動(dòng)選擇服務(wù)端ip列表中的下一個(gè)ip進(jìn)行重連。
2、當(dāng)客戶端發(fā)起訂閱時(shí),注冊(cè)中心除了會(huì)同步返回最新的服務(wù)實(shí)例列表,還會(huì)異步的通過grpc推送給該訂閱者最新的服務(wù)實(shí)例列表,這樣做的目的是為了異步更新客戶端本地緩存的服務(wù)數(shù)據(jù),一旦訂閱的服務(wù)有上下線變更,該服務(wù)所有的訂閱者會(huì)立刻收到最新的服務(wù)列表,并且將服務(wù)最新的實(shí)例數(shù)據(jù)更新到內(nèi)存。
3、當(dāng)客戶端進(jìn)行服務(wù)調(diào)用的時(shí)候,訂閱者可以通過本地維護(hù)的服務(wù)列表獲取實(shí)例,或者直接從注冊(cè)中心獲取進(jìn)行調(diào)用。
圖4 Nacos服務(wù)發(fā)現(xiàn)
Part 04
Nacos的核心功能
圖5 Nacos核心功能
除了上文提到的服務(wù)注冊(cè)和服務(wù)發(fā)現(xiàn)功能,Nacos的核心功能還包括心跳機(jī)制、服務(wù)同步和健康檢查。
1、心跳機(jī)制
服務(wù)注冊(cè)后,Nacos會(huì)為該服務(wù)分配一個(gè)心跳間隔,客戶端需要在該時(shí)間間隔內(nèi)發(fā)送心跳包,證明服務(wù)健康狀態(tài),如果客戶端在規(guī)定時(shí)間內(nèi)沒有發(fā)送心跳包,Nacos認(rèn)為該服務(wù)已下線,會(huì)從服務(wù)列表中將該服務(wù)移除,從而保障系統(tǒng)穩(wěn)定性。
2、服務(wù)同步
Nacos Server集群之間會(huì)互相同步已注冊(cè)的服務(wù),用來保證服務(wù)列表的一致性。Nacos自己實(shí)現(xiàn)了一個(gè)一致性協(xié)議名為Distro,服務(wù)注冊(cè)的時(shí)候會(huì)觸發(fā)Distro一次同步,每個(gè)Nacos節(jié)點(diǎn)之間會(huì)定時(shí)互相發(fā)送Distro數(shù)據(jù),以此保證數(shù)據(jù)最終一致。
3、服務(wù)健康檢查
Nacos Server會(huì)開啟一個(gè)定時(shí)任務(wù)用來檢查注冊(cè)服務(wù)實(shí)例的健康情況,對(duì)于超過15秒沒有收到客戶端心跳的服務(wù)實(shí)例,會(huì)將它的healthy屬性置為false,客戶端無法調(diào)用healthy為false的服務(wù),如果超過30秒沒有收到心跳,Nacos會(huì)直接將此服務(wù)剔除。
Part 05
Nacos的其他情況
常見的注冊(cè)中心組件有:Zookeeper、Eureka、Nacos、Consul等,下表為目前幾個(gè)主流注冊(cè)中心的情況對(duì)比:
圖片
Nacos支持注冊(cè)中心和配置中心,但對(duì)于小型項(xiàng)目來說,使用 Nacos 可能會(huì)過于復(fù)雜,不太適合初學(xué)者使用;Zookeeper用的最多的地方就是和Dubbo一起使用,不支持負(fù)載均衡策略,但可以通過其它組件實(shí)現(xiàn),從性能上來講,zookeeper 也無法滿足注冊(cè)中心大規(guī)模且頻繁注冊(cè)寫的場(chǎng)景;Eureka通過去中心化的集群支持保證了注冊(cè)中心的整體可用性,因?yàn)橥8木壒剩恢С忠恍┬录夹g(shù),同時(shí)Eureka屬于應(yīng)用內(nèi)的注冊(cè)方式,對(duì)應(yīng)用的侵入性太強(qiáng),且只支持Java應(yīng)用。
Part 06
總結(jié)
Nacos自從阿里集團(tuán)內(nèi)配置中心 Diamond 孵化而來,發(fā)展至今,憑借其架構(gòu)與性能優(yōu)勢(shì),已愈來愈受到眾廠商的青睞。依托其完善的社區(qū)環(huán)境,Nacos構(gòu)建了龐大而成熟的生態(tài),已成為服務(wù)發(fā)現(xiàn)解決方案領(lǐng)域中至關(guān)重要的一員。