五種注冊(cè)中心,如何選型?
大家好呀,我是樓仔。
最近發(fā)現(xiàn)很多號(hào)主發(fā)注冊(cè)中心的文章,質(zhì)量參差不齊,相關(guān)文章我之前也寫過(guò),建議直接看這篇。
這篇文章,主要講述 Zookeeper、Eureka、Nacos、Consul 和 Etcd 這 5 種注冊(cè)中心,無(wú)論是面試,還是用于技術(shù)選型,都有非常強(qiáng)的參考價(jià)值。
全文接近 8千字,有點(diǎn)長(zhǎng),建議先收藏,再慢慢看,下面是文章目錄:
圖片
01 注冊(cè)中心基本概念
1.1 什么是注冊(cè)中心?
注冊(cè)中心主要有三種角色:
- 服務(wù)提供者(RPC Server):在啟動(dòng)時(shí),向 Registry 注冊(cè)自身服務(wù),并向 Registry 定期發(fā)送心跳匯報(bào)存活狀態(tài)。
- 服務(wù)消費(fèi)者(RPC Client):在啟動(dòng)時(shí),向 Registry 訂閱服務(wù),把 Registry 返回的服務(wù)節(jié)點(diǎn)列表緩存在本地內(nèi)存中,并與 RPC Sever 建立連接。
- 服務(wù)注冊(cè)中心(Registry):用于保存 RPC Server 的注冊(cè)信息,當(dāng) RPC Server 節(jié)點(diǎn)發(fā)生變更時(shí),Registry 會(huì)同步變更,RPC Client 感知后會(huì)刷新本地 內(nèi)存中緩存的服務(wù)節(jié)點(diǎn)列表。
最后,RPC Client 從本地緩存的服務(wù)節(jié)點(diǎn)列表中,基于負(fù)載均衡算法選擇一臺(tái) RPC Sever 發(fā)起調(diào)用。
圖片
1.2 注冊(cè)中心需要實(shí)現(xiàn)功能
根據(jù)注冊(cè)中心原理的描述,注冊(cè)中心必須實(shí)現(xiàn)以下功能,偷個(gè)懶,直接貼幅圖:
圖片
02 注冊(cè)中心基礎(chǔ)掃盲
2.1 CAP理論
CAP理論是分布式架構(gòu)中重要理論:
- 一致性(Consistency):所有節(jié)點(diǎn)在同一時(shí)間具有相同的數(shù)據(jù);
- 可用性(Availability) :保證每個(gè)請(qǐng)求不管成功或者失敗都有響應(yīng);
- 分隔容忍(Partition tolerance) :系統(tǒng)中任意信息的丟失或失敗不會(huì)影響系統(tǒng)的繼續(xù)運(yùn)作。
關(guān)于 P 的理解,我覺(jué)得是在整個(gè)系統(tǒng)中某個(gè)部分,掛掉了,或者宕機(jī)了,并不影響整個(gè)系統(tǒng)的運(yùn)作或者說(shuō)使用,而可用性是,某個(gè)系統(tǒng)的某個(gè)節(jié)點(diǎn)掛了,但是并不影響系統(tǒng)的接受或者發(fā)出請(qǐng)求。
CAP 不可能都取,只能取其中2個(gè)的原因如下:
- 如果C是第一需求的話,那么會(huì)影響A的性能,因?yàn)橐獢?shù)據(jù)同步,不然請(qǐng)求結(jié)果會(huì)有差異,但是數(shù)據(jù)同步會(huì)消耗時(shí)間,期間可用性就會(huì)降低。
- 如果A是第一需求,那么只要有一個(gè)服務(wù)在,就能正常接受請(qǐng)求,但是對(duì)于返回結(jié)果變不能保證,原因是,在分布式部署的時(shí)候,數(shù)據(jù)一致的過(guò)程不可能想切線路那么快。
- 再如果,同時(shí)滿足一致性和可用性,那么分區(qū)容錯(cuò)就很難保證了,也就是單點(diǎn),也是分布式的基本核心。
2.2 分布式系統(tǒng)協(xié)議
一致性協(xié)議算法主要有Paxos、Raft、ZAB。
Paxos算法是Leslie Lamport在1990年提出的一種基于消息傳遞的一致性算法,非常難以理解,基于Paxos協(xié)議的數(shù)據(jù)同步與傳統(tǒng)主備方式最大的區(qū)別在于:Paxos只需超過(guò)半數(shù)的副本在線且相互通信正常,就可以保證服務(wù)的持續(xù)可用,且數(shù)據(jù)不丟失。
Raft是斯坦福大學(xué)的Diego Ongaro、John Ousterhout兩個(gè)人以易理解為目標(biāo)設(shè)計(jì)的一致性算法,已經(jīng)有了十幾種語(yǔ)言的Raft算法實(shí)現(xiàn)框架,較為出名的有etcd,Google的Kubernetes也是用了etcd作為他的服務(wù)發(fā)現(xiàn)框架。
Raft是Paxos的簡(jiǎn)化版,與Paxos相比,Raft強(qiáng)調(diào)的是易理解、易實(shí)現(xiàn),Raft和Paxos一樣只要保證超過(guò)半數(shù)的節(jié)點(diǎn)正常就能夠提供服務(wù)。
ZooKeeper Atomic Broadcast (ZAB, ZooKeeper原子消息廣播協(xié)議)是ZooKeeper實(shí)現(xiàn)分布式數(shù)據(jù)一致性的核心算法,ZAB借鑒Paxos算法,但又不像Paxos算法那樣,是一種通用的分布式一致性算法,它是一種特別為ZooKeeper專門設(shè)計(jì)的支持崩潰恢復(fù)的原子廣播協(xié)議。
03 常用注冊(cè)中心
這里主要介紹5種常用的注冊(cè)中心,分別為Zookeeper、Eureka、Nacos、Consul和ETCD。
3.1 Zookeeper
這個(gè)說(shuō)起來(lái)有點(diǎn)意思的是官方并沒(méi)有說(shuō)他是一個(gè)注冊(cè)中心,但是國(guó)內(nèi)Dubbo場(chǎng)景下很多都是使用Zookeeper來(lái)完成了注冊(cè)中心的功能。
當(dāng)然這有很多歷史原因,這里我們就不追溯了。ZooKeeper是非常經(jīng)典的服務(wù)注冊(cè)中心中間件,在國(guó)內(nèi)環(huán)境下,由于受到Dubbo框架的影響,大部分情況下認(rèn)為Zookeeper是RPC服務(wù)框架下注冊(cè)中心最好選擇,隨著Dubbo框架的不斷開(kāi)發(fā)優(yōu)化,和各種注冊(cè)中心組件的誕生,即使是RPC框架,現(xiàn)在的注冊(cè)中心也逐步放棄了ZooKeeper。在常用的開(kāi)發(fā)集群環(huán)境中,ZooKeeper依然起到十分重要的作用,Java體系中,大部分的集群環(huán)境都是依賴ZooKeeper管理服務(wù)的各個(gè)節(jié)點(diǎn)。
圖片
Zookeeper如何實(shí)現(xiàn)注冊(cè)中心
Zookeeper可以充當(dāng)一個(gè)服務(wù)注冊(cè)表(Service Registry),讓多個(gè)服務(wù)提供者形成一個(gè)集群,讓服務(wù)消費(fèi)者通過(guò)服務(wù)注冊(cè)表獲取具體的服務(wù)訪問(wèn)地址(Ip+端口)去訪問(wèn)具體的服務(wù)提供者。如下圖所示:
圖片
每當(dāng)一個(gè)服務(wù)提供者部署后都要將自己的服務(wù)注冊(cè)到zookeeper的某一路徑上: /{service}/{version}/{ip:port} 。
比如我們的HelloWorldService部署到兩臺(tái)機(jī)器,那么Zookeeper上就會(huì)創(chuàng)建兩條目錄:
- /HelloWorldService/1.0.0/100.19.20.01:16888
- /HelloWorldService/1.0.0/100.19.20.02:16888
這么描述有點(diǎn)不好理解,下圖更直觀:
圖片
在zookeeper中,進(jìn)行服務(wù)注冊(cè),實(shí)際上就是在zookeeper中創(chuàng)建了一個(gè)znode節(jié)點(diǎn),該節(jié)點(diǎn)存儲(chǔ)了該服務(wù)的IP、端口、調(diào)用方式(協(xié)議、序列化方式)等。該節(jié)點(diǎn)承擔(dān)著最重要的職責(zé),它由服務(wù)提供者(發(fā)布服務(wù)時(shí))創(chuàng)建,以供服務(wù)消費(fèi)者獲取節(jié)點(diǎn)中的信息,從而定位到服務(wù)提供者真正網(wǎng)絡(luò)拓?fù)湮恢靡约暗弥绾握{(diào)用。
RPC服務(wù)注冊(cè)/發(fā)現(xiàn)過(guò)程簡(jiǎn)述如下:
- 服務(wù)提供者啟動(dòng)時(shí),會(huì)將其服務(wù)名稱,ip地址注冊(cè)到配置中心。
- 服務(wù)消費(fèi)者在第一次調(diào)用服務(wù)時(shí),會(huì)通過(guò)注冊(cè)中心找到相應(yīng)的服務(wù)的IP地址列表,并緩存到本地,以供后續(xù)使用。當(dāng)消費(fèi)者調(diào)用服務(wù)時(shí),不會(huì)再去請(qǐng)求注冊(cè)中心,而是直接通過(guò)負(fù)載均衡算法從IP列表中取一個(gè)服務(wù)提供者的服務(wù)器調(diào)用服務(wù)。
- 當(dāng)服務(wù)提供者的某臺(tái)服務(wù)器宕機(jī)或下線時(shí),相應(yīng)的ip會(huì)從服務(wù)提供者IP列表中移除。同時(shí),注冊(cè)中心會(huì)將新的服務(wù)IP地址列表發(fā)送給服務(wù)消費(fèi)者機(jī)器,緩存在消費(fèi)者本機(jī)。
- 當(dāng)某個(gè)服務(wù)的所有服務(wù)器都下線了,那么這個(gè)服務(wù)也就下線了。
- 同樣,當(dāng)服務(wù)提供者的某臺(tái)服務(wù)器上線時(shí),注冊(cè)中心會(huì)將新的服務(wù)IP地址列表發(fā)送給服務(wù)消費(fèi)者機(jī)器,緩存在消費(fèi)者本機(jī)。
- 服務(wù)提供方可以根據(jù)服務(wù)消費(fèi)者的數(shù)量來(lái)作為服務(wù)下線的依據(jù)。
zookeeper提供了“心跳檢測(cè)”功能:它會(huì)定時(shí)向各個(gè)服務(wù)提供者發(fā)送一個(gè)請(qǐng)求(實(shí)際上建立的是一個(gè) socket 長(zhǎng)連接),如果長(zhǎng)期沒(méi)有響應(yīng),服務(wù)中心就認(rèn)為該服務(wù)提供者已經(jīng)“掛了”,并將其剔除。
比如100.100.0.237這臺(tái)機(jī)器如果宕機(jī)了,那么zookeeper上的路徑就會(huì)只剩/HelloWorldService/1.0.0/100.100.0.238:16888。
Zookeeper的Watch機(jī)制其實(shí)就是一種推拉結(jié)合的模式:
- 服務(wù)消費(fèi)者會(huì)去監(jiān)聽(tīng)相應(yīng)路徑(/HelloWorldService/1.0.0),一旦路徑上的數(shù)據(jù)有任務(wù)變化(增加或減少),Zookeeper只會(huì)發(fā)送一個(gè)事件類型和節(jié)點(diǎn)信息給關(guān)注的客戶端,而不會(huì)包括具體的變更內(nèi)容,所以事件本身是輕量級(jí)的,這就是推的部分。
- 收到變更通知的客戶端需要自己去拉變更的數(shù)據(jù),這就是拉的部分。
Zookeeper不適合作為注冊(cè)中心
作為一個(gè)分布式協(xié)同服務(wù),ZooKeeper非常好,但是對(duì)于Service發(fā)現(xiàn)服務(wù)來(lái)說(shuō)就不合適了,因?yàn)閷?duì)于Service發(fā)現(xiàn)服務(wù)來(lái)說(shuō)就算是返回了包含不實(shí)的信息的結(jié)果也比什么都不返回要好。所以當(dāng)向注冊(cè)中心查詢服務(wù)列表時(shí),我們可以容忍注冊(cè)中心返回的是幾分鐘以前的注冊(cè)信息,但不能接受服務(wù)直接down掉不可用。
但是zk會(huì)出現(xiàn)這樣一種情況,當(dāng)master節(jié)點(diǎn)因?yàn)榫W(wǎng)絡(luò)故障與其他節(jié)點(diǎn)失去聯(lián)系時(shí),剩余節(jié)點(diǎn)會(huì)重新進(jìn)行l(wèi)eader選舉。問(wèn)題在于,選舉leader的時(shí)間太長(zhǎng),30 ~ 120s, 且選舉期間整個(gè)zk集群都是不可用的,這就導(dǎo)致在選舉期間注冊(cè)服務(wù)癱瘓。在云部署的環(huán)境下,因網(wǎng)絡(luò)問(wèn)題使得zk集群失去master節(jié)點(diǎn)是較大概率會(huì)發(fā)生的事,雖然服務(wù)能夠最終恢復(fù),但是漫長(zhǎng)的選舉時(shí)間導(dǎo)致的注冊(cè)長(zhǎng)期不可用是不能容忍的。
所以說(shuō),作為注冊(cè)中心,可用性的要求要高于一致性!
在 CAP 模型中,Zookeeper整體遵循一致性(CP)原則,即在任何時(shí)候?qū)?Zookeeper 的訪問(wèn)請(qǐng)求能得到一致的數(shù)據(jù)結(jié)果,但是當(dāng)機(jī)器下線或者宕機(jī)時(shí),不能保證服務(wù)可用性。
那為什么Zookeeper不使用最終一致性(AP)模型呢?因?yàn)檫@個(gè)依賴Zookeeper的核心算法是ZAB,所有設(shè)計(jì)都是為了強(qiáng)一致性。這個(gè)對(duì)于分布式協(xié)調(diào)系統(tǒng),完全沒(méi)沒(méi)有毛病,但是你如果將Zookeeper為分布式協(xié)調(diào)服務(wù)所做的一致性保障,用在注冊(cè)中心,或者說(shuō)服務(wù)發(fā)現(xiàn)場(chǎng)景,這個(gè)其實(shí)就不合適。
3.2 Eureka
Eureka 架構(gòu)圖
圖片
什么,上面這幅圖看起來(lái)很復(fù)雜?那我給你貼個(gè)簡(jiǎn)化版:
圖片
Eureka 特點(diǎn)
- 可用性(AP原則):Eureka 在設(shè)計(jì)時(shí)就緊遵AP原則,Eureka的集群中,只要有一臺(tái)Eureka還在,就能保證注冊(cè)服務(wù)可用,只不過(guò)查到的信息可能不是最新的(不保證強(qiáng)一致性)。
- 去中心化架構(gòu):Eureka Server 可以運(yùn)行多個(gè)實(shí)例來(lái)構(gòu)建集群,不同于 ZooKeeper 的選舉 leader 的過(guò)程,Eureka Server 采用的是Peer to Peer 對(duì)等通信。這是一種去中心化的架構(gòu),無(wú) master/slave 之分,每一個(gè) Peer 都是對(duì)等的。節(jié)點(diǎn)通過(guò)彼此互相注冊(cè)來(lái)提高可用性,每個(gè)節(jié)點(diǎn)需要添加一個(gè)或多個(gè)有效的 serviceUrl 指向其他節(jié)點(diǎn)。每個(gè)節(jié)點(diǎn)都可被視為其他節(jié)點(diǎn)的副本。
- 請(qǐng)求自動(dòng)切換:在集群環(huán)境中如果某臺(tái) Eureka Server 宕機(jī),Eureka Client 的請(qǐng)求會(huì)自動(dòng)切換到新的 Eureka Server 節(jié)點(diǎn)上,當(dāng)宕機(jī)的服務(wù)器重新恢復(fù)后,Eureka 會(huì)再次將其納入到服務(wù)器集群管理之中。
- 節(jié)點(diǎn)間操作復(fù)制:當(dāng)節(jié)點(diǎn)開(kāi)始接受客戶端請(qǐng)求時(shí),所有的操作都會(huì)在節(jié)點(diǎn)間進(jìn)行復(fù)制操作,將請(qǐng)求復(fù)制到該 Eureka Server 當(dāng)前所知的其它所有節(jié)點(diǎn)中。
- 自動(dòng)注冊(cè)&心跳:當(dāng)一個(gè)新的 Eureka Server 節(jié)點(diǎn)啟動(dòng)后,會(huì)首先嘗試從鄰近節(jié)點(diǎn)獲取所有注冊(cè)列表信息,并完成初始化。Eureka Server 通過(guò) getEurekaServiceUrls() 方法獲取所有的節(jié)點(diǎn),并且會(huì)通過(guò)心跳契約的方式定期更新。
- 自動(dòng)下線:默認(rèn)情況下,如果 Eureka Server 在一定時(shí)間內(nèi)沒(méi)有接收到某個(gè)服務(wù)實(shí)例的心跳(默認(rèn)周期為30秒),Eureka Server 將會(huì)注銷該實(shí)例(默認(rèn)為90秒, eureka.instance.lease-expiration-duration-in-seconds 進(jìn)行自定義配置)。
- 保護(hù)模式:當(dāng) Eureka Server 節(jié)點(diǎn)在短時(shí)間內(nèi)丟失過(guò)多的心跳時(shí),那么這個(gè)節(jié)點(diǎn)就會(huì)進(jìn)入自我保護(hù)模式。
除了上述特點(diǎn),Eureka還有一種自我保護(hù)機(jī)制,如果在15分鐘內(nèi)超過(guò) 85% 的節(jié)點(diǎn)都沒(méi)有正常的心跳,那么Eureka就認(rèn)為客戶端與注冊(cè)中心出現(xiàn)了網(wǎng)絡(luò)故障,此時(shí)會(huì)出現(xiàn)以下幾種情況:
- Eureka不再?gòu)淖?cè)表中移除因?yàn)殚L(zhǎng)時(shí)間沒(méi)有收到心跳而過(guò)期的服務(wù);
- Eureka仍然能夠接受新服務(wù)注冊(cè)和查詢請(qǐng)求,但是不會(huì)被同步到其它節(jié)點(diǎn)上(即保證當(dāng)前節(jié)點(diǎn)依然可用)
- 當(dāng)網(wǎng)絡(luò)穩(wěn)定時(shí),當(dāng)前實(shí)例新注冊(cè)的信息會(huì)被同步到其它節(jié)點(diǎn)中。
Eureka工作流程
了解完 Eureka 核心概念,自我保護(hù)機(jī)制,以及集群內(nèi)的工作原理后,我們來(lái)整體梳理一下 Eureka 的工作流程:
- Eureka Server 啟動(dòng)成功,等待服務(wù)端注冊(cè)。在啟動(dòng)過(guò)程中如果配置了集群,集群之間定時(shí)通過(guò) Replicate 同步注冊(cè)表,每個(gè) Eureka Server 都存在獨(dú)立完整的服務(wù)注冊(cè)表信息。
- Eureka Client 啟動(dòng)時(shí)根據(jù)配置的 Eureka Server 地址去注冊(cè)中心注冊(cè)服務(wù)。
- Eureka Client 會(huì)每 30s 向 Eureka Server 發(fā)送一次心跳請(qǐng)求,證明客戶端服務(wù)正常。
- 當(dāng) Eureka Server 90s 內(nèi)沒(méi)有收到 Eureka Client 的心跳,注冊(cè)中心則認(rèn)為該節(jié)點(diǎn)失效,會(huì)注銷該實(shí)例。
- 單位時(shí)間內(nèi) Eureka Server 統(tǒng)計(jì)到有大量的 Eureka Client 沒(méi)有上送心跳,則認(rèn)為可能為網(wǎng)絡(luò)異常,進(jìn)入自我保護(hù)機(jī)制,不再剔除沒(méi)有上送心跳的客戶端。
- 當(dāng) Eureka Client 心跳請(qǐng)求恢復(fù)正常之后,Eureka Server 自動(dòng)退出自我保護(hù)模式。
- Eureka Client 定時(shí)全量或者增量從注冊(cè)中心獲取服務(wù)注冊(cè)表,并且將獲取到的信息緩存到本地。
- 服務(wù)調(diào)用時(shí),Eureka Client 會(huì)先從本地緩存找尋調(diào)取的服務(wù)。如果獲取不到,先從注冊(cè)中心刷新注冊(cè)表,再同步到本地緩存。
- Eureka Client 獲取到目標(biāo)服務(wù)器信息,發(fā)起服務(wù)調(diào)用。
- Eureka Client 程序關(guān)閉時(shí)向 Eureka Server 發(fā)送取消請(qǐng)求,Eureka Server 將實(shí)例從注冊(cè)表中刪除。
通過(guò)分析 Eureka 工作原理,我可以明顯地感覺(jué)到 Eureka 的設(shè)計(jì)之巧妙,完美地解決了注冊(cè)中心的穩(wěn)定性和高可用性。
Eureka 為了保障注冊(cè)中心的高可用性,容忍了數(shù)據(jù)的非強(qiáng)一致性,服務(wù)節(jié)點(diǎn)間的數(shù)據(jù)可能不一致, Client-Server 間的數(shù)據(jù)可能不一致。比較適合跨越多機(jī)房、對(duì)注冊(cè)中心服務(wù)可用性要求較高的使用場(chǎng)景。
3.3 Nacos
以下內(nèi)容摘抄自Nacos官網(wǎng):https://nacos.io/zh-cn/docs/what-is-nacos.html
圖片
Nacos 致力于幫助您發(fā)現(xiàn)、配置和管理微服務(wù)。Nacos 提供了一組簡(jiǎn)單易用的特性集,幫助您快速實(shí)現(xiàn)動(dòng)態(tài)服務(wù)發(fā)現(xiàn)、服務(wù)配置、服務(wù)元數(shù)據(jù)及流量管理。
Nacos 幫助您更敏捷和容易地構(gòu)建、交付和管理微服務(wù)平臺(tái)。Nacos 是構(gòu)建以“服務(wù)”為中心的現(xiàn)代應(yīng)用架構(gòu) (例如微服務(wù)范式、云原生范式) 的服務(wù)基礎(chǔ)設(shè)施。
圖片
Nacos 主要特點(diǎn)
服務(wù)發(fā)現(xiàn)和服務(wù)健康監(jiān)測(cè):
- Nacos 支持基于 DNS 和基于 RPC 的服務(wù)發(fā)現(xiàn)。服務(wù)提供者使用原生SDK、OpenAPI、或一個(gè)獨(dú)立的Agent TODO注冊(cè) Service 后,服務(wù)消費(fèi)者可以使用DNS TODO 或HTTP&API查找和發(fā)現(xiàn)服務(wù)。
- Nacos 提供對(duì)服務(wù)的實(shí)時(shí)的健康檢查,阻止向不健康的主機(jī)或服務(wù)實(shí)例發(fā)送請(qǐng)求。Nacos 支持傳輸層 (PING 或 TCP)和應(yīng)用層 (如 HTTP、MySQL、用戶自定義)的健康檢查。對(duì)于復(fù)雜的云環(huán)境和網(wǎng)絡(luò)拓?fù)洵h(huán)境中(如 VPC、邊緣網(wǎng)絡(luò)等)服務(wù)的健康檢查,Nacos 提供了 agent 上報(bào)模式和服務(wù)端主動(dòng)檢測(cè)2種健康檢查模式。Nacos 還提供了統(tǒng)一的健康檢查儀表盤,幫助您根據(jù)健康狀態(tài)管理服務(wù)的可用性及流量。
動(dòng)態(tài)配置服務(wù):
- 動(dòng)態(tài)配置服務(wù)可以讓您以中心化、外部化和動(dòng)態(tài)化的方式管理所有環(huán)境的應(yīng)用配置和服務(wù)配置。
- 動(dòng)態(tài)配置消除了配置變更時(shí)重新部署應(yīng)用和服務(wù)的需要,讓配置管理變得更加高效和敏捷。
- 配置中心化管理讓實(shí)現(xiàn)無(wú)狀態(tài)服務(wù)變得更簡(jiǎn)單,讓服務(wù)按需彈性擴(kuò)展變得更容易。
- Nacos 提供了一個(gè)簡(jiǎn)潔易用的UI (控制臺(tái)樣例 Demo) 幫助您管理所有的服務(wù)和應(yīng)用的配置。Nacos 還提供包括配置版本跟蹤、金絲雀發(fā)布、一鍵回滾配置以及客戶端配置更新?tīng)顟B(tài)跟蹤在內(nèi)的一系列開(kāi)箱即用的配置管理特性,幫助您更安全地在生產(chǎn)環(huán)境中管理配置變更和降低配置變更帶來(lái)的風(fēng)險(xiǎn)。
動(dòng)態(tài) DNS 服務(wù):
- 動(dòng)態(tài) DNS 服務(wù)支持權(quán)重路由,讓您更容易地實(shí)現(xiàn)中間層負(fù)載均衡、更靈活的路由策略、流量控制以及數(shù)據(jù)中心內(nèi)網(wǎng)的簡(jiǎn)單DNS解析服務(wù)。動(dòng)態(tài)DNS服務(wù)還能讓您更容易地實(shí)現(xiàn)以 DNS 協(xié)議為基礎(chǔ)的服務(wù)發(fā)現(xiàn),以幫助您消除耦合到廠商私有服務(wù)發(fā)現(xiàn) API 上的風(fēng)險(xiǎn)。
- Nacos 提供了一些簡(jiǎn)單的 DNS APIs TODO 幫助您管理服務(wù)的關(guān)聯(lián)域名和可用的 IP:PORT 列表。
小節(jié)一下:
- Nacos是阿里開(kāi)源的,支持基于 DNS 和基于 RPC 的服務(wù)發(fā)現(xiàn)。
- Nacos的注冊(cè)中心支持CP也支持AP,對(duì)他來(lái)說(shuō)只是一個(gè)命令的切換,隨你玩,還支持各種注冊(cè)中心遷移到Nacos,反正一句話,只要你想要的他就有。
- Nacos除了服務(wù)的注冊(cè)發(fā)現(xiàn)之外,還支持動(dòng)態(tài)配置服務(wù),一句話概括就是Nacos = Spring Cloud注冊(cè)中心 + Spring Cloud配置中心。
3.4 Consul
Consul 是 HashiCorp 公司推出的開(kāi)源工具,用于實(shí)現(xiàn)分布式系統(tǒng)的服務(wù)發(fā)現(xiàn)與配置。與其它分布式服務(wù)注冊(cè)與發(fā)現(xiàn)的方案,Consul 的方案更“一站式”,內(nèi)置了服務(wù)注冊(cè)與發(fā)現(xiàn)框 架、分布一致性協(xié)議實(shí)現(xiàn)、健康檢查、Key/Value 存儲(chǔ)、多數(shù)據(jù)中心方案,不再需要依賴其它工具(比如 ZooKeeper 等)。
Consul 使用起來(lái)也較為簡(jiǎn)單,使用 Go 語(yǔ)言編寫,因此具有天然可移植性(支持Linux、windows和Mac OS X);安裝包僅包含一個(gè)可執(zhí)行文件,方便部署,與 Docker 等輕量級(jí)容器可無(wú)縫配合。
Consul 的調(diào)用過(guò)程
- 當(dāng) Producer 啟動(dòng)的時(shí)候,會(huì)向 Consul 發(fā)送一個(gè) post 請(qǐng)求,告訴 Consul 自己的 IP 和 Port;
- Consul 接收到 Producer 的注冊(cè)后,每隔 10s(默認(rèn))會(huì)向 Producer 發(fā)送一個(gè)健康檢查的請(qǐng)求,檢驗(yàn) Producer 是否健康;
- 當(dāng) Consumer 發(fā)送 GET 方式請(qǐng)求 /api/address 到 Producer 時(shí),會(huì)先從 Consul 中拿到一個(gè)存儲(chǔ)服務(wù) IP 和 Port 的臨時(shí)表,從表中拿到 Producer 的 IP 和 Port 后再發(fā)送 GET 方式請(qǐng)求 /api/address;
- 該臨時(shí)表每隔 10s 會(huì)更新,只包含有通過(guò)了健康檢查的 Producer。
圖片
Consul 主要特征
- CP模型,使用 Raft 算法來(lái)保證強(qiáng)一致性,不保證可用性;
- 支持服務(wù)注冊(cè)與發(fā)現(xiàn)、健康檢查、KV Store功能。
- 支持多數(shù)據(jù)中心,可以避免單數(shù)據(jù)中心的單點(diǎn)故障,而其部署則需要考慮網(wǎng)絡(luò)延遲, 分片等情況等。
- 支持安全服務(wù)通信,Consul可以為服務(wù)生成和分發(fā)TLS證書(shū),以建立相互的TLS連接。
- 支持 http 和 dns 協(xié)議接口;
- 官方提供 web 管理界面。
多數(shù)據(jù)中心
Consul支持開(kāi)箱即用的多數(shù)據(jù)中心,這意味著用戶不需要擔(dān)心需要建立額外的抽象層讓業(yè)務(wù)擴(kuò)展到多個(gè)區(qū)域。
圖片
在上圖中有兩個(gè)DataCenter,他們通過(guò)Internet互聯(lián),同時(shí)請(qǐng)注意為了提高通信效率,只有Server節(jié)點(diǎn)才加入跨數(shù)據(jù)中心的通信。
在單個(gè)數(shù)據(jù)中心中,Consul分為Client和Server兩種節(jié)點(diǎn)(所有的節(jié)點(diǎn)也被稱為Agent),Server節(jié)點(diǎn)保存數(shù)據(jù),Client負(fù)責(zé)健康檢查及轉(zhuǎn)發(fā)數(shù)據(jù)請(qǐng)求到Server;Server節(jié)點(diǎn)有一個(gè)Leader和多個(gè)Follower,Leader節(jié)點(diǎn)會(huì)將數(shù)據(jù)同步到Follower,Server的數(shù)量推薦是3個(gè)或者5個(gè),在Leader掛掉的時(shí)候會(huì)啟動(dòng)選舉機(jī)制產(chǎn)生一個(gè)新的Leader。
集群內(nèi)的Consul節(jié)點(diǎn)通過(guò)gossip協(xié)議(流言協(xié)議)維護(hù)成員關(guān)系,也就是說(shuō)某個(gè)節(jié)點(diǎn)了解集群內(nèi)現(xiàn)在還有哪些節(jié)點(diǎn),這些節(jié)點(diǎn)是Client還是Server。單個(gè)數(shù)據(jù)中心的流言協(xié)議同時(shí)使用TCP和UDP通信,并且都使用8301端口??鐢?shù)據(jù)中心的流言協(xié)議也同時(shí)使用TCP和UDP通信,端口使用8302。
集群內(nèi)數(shù)據(jù)的讀寫請(qǐng)求既可以直接發(fā)到Server,也可以通過(guò)Client使用RPC轉(zhuǎn)發(fā)到Server,請(qǐng)求最終會(huì)到達(dá)Leader節(jié)點(diǎn),在允許數(shù)據(jù)延時(shí)的情況下,讀請(qǐng)求也可以在普通的Server節(jié)點(diǎn)完成,集群內(nèi)數(shù)據(jù)的讀寫和復(fù)制都是通過(guò)TCP的8300端口完成。
3.5 ETCD
etcd是一個(gè)Go言編寫的分布式、高可用的一致性鍵值存儲(chǔ)系統(tǒng),用于提供可靠的分布式鍵值存儲(chǔ)、配置共享和服務(wù)發(fā)現(xiàn)等功能。
ETCD 特點(diǎn)
- 易使用:基于HTTP+JSON的API讓你用curl就可以輕松使用;
- 易部署:使用Go語(yǔ)言編寫,跨平臺(tái),部署和維護(hù)簡(jiǎn)單;
- 強(qiáng)一致:使用Raft算法充分保證了分布式系統(tǒng)數(shù)據(jù)的強(qiáng)一致性;
- 高可用:具有容錯(cuò)能力,假設(shè)集群有n個(gè)節(jié)點(diǎn),當(dāng)有(n-1)/2節(jié)點(diǎn)發(fā)送故障,依然能提供服務(wù);
- 持久化:數(shù)據(jù)更新后,會(huì)通過(guò)WAL格式數(shù)據(jù)持久化到磁盤,支持Snapshot快照;
- 快速:每個(gè)實(shí)例每秒支持一千次寫操作,極限寫性能可達(dá)10K QPS;
- 安全:可選SSL客戶認(rèn)證機(jī)制;
- ETCD 3.0:除了上述功能,還支持gRPC通信、watch機(jī)制。
ETCD 框架
etcd主要分為四個(gè)部分:
- HTTP Server:用于處理用戶發(fā)送的API請(qǐng)求以及其它etcd節(jié)點(diǎn)的同步與心跳信息請(qǐng)求。
- Store:用于處理etcd支持的各類功能的事務(wù),包括數(shù)據(jù)索引、節(jié)點(diǎn)狀態(tài)變更、監(jiān)控與反饋、事件處理與執(zhí)行等等,是etcd對(duì)用戶提供的大多數(shù)API功能的具體實(shí)現(xiàn)。
- Raft:Raft強(qiáng)一致性算法的具體實(shí)現(xiàn),是etcd的核心。
- WAL:Write Ahead Log(預(yù)寫式日志),是etcd的數(shù)據(jù)存儲(chǔ)方式。除了在內(nèi)存中存有所有數(shù)據(jù)的狀態(tài)以及節(jié)點(diǎn)的索引以外,etcd就通過(guò)WAL進(jìn)行持久化存儲(chǔ)。WAL中,所有的數(shù)據(jù)提交前都會(huì)事先記錄日志。Snapshot是為了防止數(shù)據(jù)過(guò)多而進(jìn)行的狀態(tài)快照;Entry表示存儲(chǔ)的具體日志內(nèi)容。
圖片
通常,一個(gè)用戶的請(qǐng)求發(fā)送過(guò)來(lái),會(huì)經(jīng)由HTTP Server轉(zhuǎn)發(fā)給Store進(jìn)行具體的事務(wù)處理,如果涉及到節(jié)點(diǎn)的修改,則交給Raft模塊進(jìn)行狀態(tài)的變更、日志的記錄,然后再同步給別的etcd節(jié)點(diǎn)以確認(rèn)數(shù)據(jù)提交,最后進(jìn)行數(shù)據(jù)的提交,再次同步。
04 注冊(cè)中心對(duì)比&選型
4.1 注冊(cè)中心對(duì)比
圖片
圖片
- 服務(wù)健康檢查:Euraka 使用時(shí)需要顯式配置健康檢查支持;Zookeeper、Etcd 則在失去了和服務(wù)進(jìn)程的連接情況下任務(wù)不健康,而 Consul 相對(duì)更為詳細(xì)點(diǎn),比如內(nèi)存是否已使用了90%,文件系統(tǒng)的空間是不是快不足了。
- 多數(shù)據(jù)中心:Consul 和 Nacos 都支持,其他的產(chǎn)品則需要額外的開(kāi)發(fā)工作來(lái)實(shí)現(xiàn)。
- KV 存儲(chǔ)服務(wù):除了 Eureka,其他幾款都能夠?qū)ν庵С?k-v 的存儲(chǔ)服務(wù),所以后面會(huì)講到這幾款產(chǎn)品追求高一致性的重要原因。而提供存儲(chǔ)服務(wù),也能夠較好的轉(zhuǎn)化為動(dòng)態(tài)配置服務(wù)哦。
- CAP 理論的取舍:
- Eureka 是典型的 AP,Nacos可以配置為 AP,作為分布式場(chǎng)景下的服務(wù)發(fā)現(xiàn)的產(chǎn)品較為合適,服務(wù)發(fā)現(xiàn)場(chǎng)景的可用性優(yōu)先級(jí)較高,一致性并不是特別致命。
- 而Zookeeper、Etcd、Consul則是 CP 類型犧牲可用性,在服務(wù)發(fā)現(xiàn)場(chǎng)景并沒(méi)太大優(yōu)勢(shì);
- Watch的支持:Zookeeper 支持服務(wù)器端推送變化,其它都通過(guò)長(zhǎng)輪詢的方式來(lái)實(shí)現(xiàn)變化的感知。
- 自身集群的監(jiān)控:除了Zookeeper和Nacos,其它幾款都默認(rèn)支持 metrics,運(yùn)維者可以搜集并報(bào)警這些度量信息達(dá)到監(jiān)控目的。
- Spring Cloud的集成:目前都有相對(duì)應(yīng)的 boot starter,提供了集成能力。
4.2 注冊(cè)中心選型
關(guān)于注冊(cè)中心的對(duì)比和選型,其實(shí)上面已經(jīng)講的非常清楚了,我給出一些個(gè)人理解:
- 關(guān)于CP還是AP的選擇:選擇 AP,因?yàn)榭捎眯愿哂谝恢滦?,所以更傾向 Eureka 和 Nacos;關(guān)于Eureka、Nacos如何選擇,哪個(gè)讓我做的事少,我就選擇哪個(gè),顯然 Nacos 幫我們做了更多的事。
- 技術(shù)體系:Etcd 和 Consul 都是Go開(kāi)發(fā)的,Eureka、Nacos、Zookeeper 和 Zookeeper 都是Java開(kāi)發(fā)的,可能項(xiàng)目屬于不同的技術(shù)棧,會(huì)偏向選擇對(duì)應(yīng)的技術(shù)體系。
- 高可用:這幾款開(kāi)源產(chǎn)品都已經(jīng)考慮如何搭建高可用集群,有些差別而已;
- 產(chǎn)品的活躍度:這幾款開(kāi)源產(chǎn)品整體上都比較活躍。