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