前言
服務發(fā)現是一個古老的話題,當應用開始脫離單機運行和訪問時,服務發(fā)現就誕生了。目前的網絡架構是每個主機都有一個獨立的IP地址肋乍,那么服務發(fā)現基本上都是通過某種方式獲取到服務所部署的IP地址。DNS協議是最早將一個網絡名稱翻譯為網絡IP的協議敷存,在最初的架構選型中墓造,DNS+LVS+Nginx基本可以滿足所有的RESTful服務的發(fā)現,此時服務的IP列表通常配置在Nginx或者LVS锚烦。后來出現了RPC服務觅闽,服務的上下線更加頻繁,人們開始尋求一種能夠支持動態(tài)上下線并且推送IP列表變化的注冊中心產品涮俄。
ZooKeeper是一款經典的服務注冊中心產品(雖然它最初的定位并不在于此)谱煤,在很長一段時間里,它是國人在提起RPC服務注冊中心時心里想到的唯一選擇禽拔,這很大程度上與Dubbo在中國的普及程度有關刘离。Consul和Eureka都出現于2014年,Consul在設計上把很多分布式服務治理上要用到的功能都包含在內睹栖,可以支持服務注冊硫惕、健康檢查、配置管理野来、Service Mesh等恼除。而Eureka則借著微服務概念的流行,與SpringCloud生態(tài)的深度結合曼氛,也獲取了大量的用戶豁辉。去年開源的Nacos,則攜帶著阿里巴巴大規(guī)模服務生產經驗舀患,試圖在服務注冊和配置管理這個市場上徽级,提供給用戶一個新的選擇。
圖1 服務發(fā)現
當市面上有多種相似功能的產品出現時聊浅,人們往往希望知道這些產品相比較的優(yōu)劣餐抢。產品本身的定位會決定它包含了哪些功能现使,而產品架構的設計,則會影響產品的性能和可用性等旷痕。開源產品的一個優(yōu)勢是開發(fā)人員可以去閱讀源代碼碳锈,理解產品的功能設計和架構設計,同時也可以通過本地部署來測試性能欺抗,隨之而來的是各種產品的對比文章售碳。不過當前關于注冊中心的對比,往往停留在表面的功能對比上绞呈,對架構或者性能并沒有非常深入的探討贸人。
另一個現象是服務注冊中心往往隱藏在服務框架背后,作為默默支持的產品报强。優(yōu)秀的服務框架往往會支持多種配置中心灸姊,但是注冊中心的選擇依然強關聯與服務框架拱燃,一種普遍的情況是一種服務框架會帶一個默認的服務注冊中心秉溉。這樣雖然免去了用戶在選型上的煩惱,但是單個注冊中心的局限性碗誉,導致用戶使用多個服務框架時召嘶,必須部署多套完全不同的注冊中心,這些注冊中心之間的數據協同也是一個問題哮缺。
本文是一篇來自Nacos項目組的文章弄跌,雖然是來自Nacos,我們依然力求公正和客觀的去看待服務發(fā)現所有產品的各個維度尝苇。本文不僅僅包含常見服務注冊中心產品的對比铛只,還試圖從我們的經驗和調研中總結和闡述服務注冊中心產品設計上應該去遵循和考慮的要點。
數據模型
注冊中心的核心數據是服務的名字和它對應的網絡地址糠溜,當服務注冊了多個實例時淳玩,我們需要對不健康的實例進行過濾或者針對實例的一些特征進行流量的分配,那么就需要在實例上存儲一些例如健康狀態(tài)非竿、權重等屬性蜕着。隨著服務規(guī)模的擴大,漸漸的又需要在整個服務級別設定一些權限規(guī)則红柱、以及對所有實例都生效的一些開關承匣,于是在服務級別又會設立一些屬性。再往后锤悄,我們又發(fā)現單個服務的實例又會有劃分為多個子集的需求韧骗,例如一個服務是多機房部署的,那么可能需要對每個機房的實例做不同的配置零聚,這樣又需要在服務和實例之間再設定一個數據級別宽闲。
Zookeeper沒有針對服務發(fā)現設計數據模型众眨,它的數據是以一種更加抽象的樹形K-V組織的,因此理論上可以存儲任何語義的數據容诬。而Eureka或者Consul都是做到了實例級別的數據擴展娩梨,這可以滿足大部分的場景,不過無法滿足大規(guī)模和多環(huán)境的服務數據存儲览徒。Nacos在經過內部多年生產經驗后提煉出的數據模型狈定,則是一種服務-集群-實例的三層模型。如上文所說习蓬,這樣基本可以滿足服務在所有場景下的數據存儲和管理纽什。
圖2 服務的分級模型
Nacos的數據模型雖然相對復雜,但是它并不強制你使用它里面的所有數據躲叼,在大多數場景下芦缰,你可以選擇忽略這些數據屬性,此時可以降維成和Eureka和Consul一樣的數據模型枫慷。
另外一個需要考慮的是數據的隔離模型让蕾,作為一個共享服務型的組件,需要能夠在多個用戶或者業(yè)務方使用的情況下或听,保證數據的隔離和安全探孝,這在稍微大一點的業(yè)務場景中非常常見。另一方面服務注冊中心往往會支持云上部署誉裆,此時就要求服務注冊中心的數據模型能夠適配云上的通用模型顿颅。Zookeeper、Consul和Eureka在開源層面都沒有很明確的針對服務隔離的模型足丢,Nacos則在一開始就考慮到如何讓用戶能夠以多種維度進行數據隔離粱腻,同時能夠平滑的遷移到阿里云上對應的商業(yè)化產品。
圖3 服務的邏輯隔離模型
Nacos提供了四層的數據邏輯隔離模型斩跌,用戶賬號對應的可能是一個企業(yè)或者獨立的個體绍些,這個數據一般情況下不會透傳到服務注冊中心。一個用戶賬號可以新建多個命名空間滔驶,每個命名空間對應一個客戶端實例遇革,這個命名空間對應的注冊中心物理集群是可以根據規(guī)則進行路由的,這樣可以讓注冊中心內部的升級和遷移對用戶是無感知的揭糕,同時可以根據用戶的級別萝快,為用戶提供不同服務級別的物理集群。再往下是服務分組和服務名組成的二維服務標識著角,可以滿足接口級別的服務隔離揪漩。
Nacos 1.0.0介紹的另外一個新特性是:臨時實例和持久化實例。在定義上區(qū)分臨時實例和持久化實例的關鍵是健康檢查的方式吏口。臨時實例使用客戶端上報模式奄容,而持久化實例使用服務端反向探測模式冰更。臨時實例需要能夠自動摘除不健康實例,而且無需持久化存儲實例昂勒,那么這種實例就適用于類Gossip的協議蜀细。右邊的持久化實例使用服務端探測的健康檢查方式,因為客戶端不會上報心跳戈盈,那么自然就不能去自動摘除下線的實例奠衔。
圖4 臨時實例和持久化實例
在大中型的公司里,這兩種類型的服務往往都有塘娶。一些基礎的組件例如數據庫归斤、緩存等,這些往往不能上報心跳刁岸,這種類型的服務在注冊時脏里,就需要作為持久化實例注冊。而上層的業(yè)務服務虹曙,例如微服務或者Dubbo服務迫横,服務的Provider端支持添加匯報心跳的邏輯,此時就可以使用動態(tài)服務的注冊方式根吁。
數據一致性
數據一致性是分布式系統(tǒng)永恒的話題员淫,Paxos協議的艱深更讓數據一致性成為程序員大牛們吹水的常見話題合蔽。不過從協議層面上看击敌,一致性的選型已經很長時間沒有新的成員加入了。目前來看基本可以歸為兩家:一種是基于Leader的非對等部署的單點寫一致性拴事,一種是對等部署的多寫一致性沃斤。當我們選用服務注冊中心的時候,并沒有一種協議能夠覆蓋所有場景刃宵,例如當注冊的服務節(jié)點不會定時發(fā)送心跳到注冊中心時衡瓶,強一致協議看起來是唯一的選擇,因為無法通過心跳來進行數據的補償注冊牲证,第一次注冊就必須保證數據不會丟失哮针。而當客戶端會定時發(fā)送心跳來匯報健康狀態(tài)時,第一次的注冊的成功率并不是非常關鍵(當然也很關鍵坦袍,只是相對來說我們容忍數據的少量寫失斒帷),因為后續(xù)還可以通過心跳再把數據補償上來捂齐,此時Paxos協議的單點瓶頸就會不太劃算了蛮放,這也是Eureka為什么不采用Paxos協議而采用自定義的Renew機制的原因。
這兩種數據一致性協議有各自的使用場景奠宜,對服務注冊的需求不同包颁,就會導致使用不同的協議瞻想。在這里可以發(fā)現,Zookeeper在Dubbo體系下表現出的行為娩嚼,其實采用Eureka的Renew機制更加合適蘑险,因為Dubbo服務往Zookeeper注冊的就是臨時節(jié)點,需要定時發(fā)心跳到Zookeeper來續(xù)約節(jié)點岳悟,并允許服務下線時漠其,將Zookeeper上相應的節(jié)點摘除。Zookeeper使用ZAB協議雖然保證了數據的強一致竿音,但是它的機房容災能力的缺乏和屎,無法適應一些大型場景。
Nacos因為要支持多種服務類型的注冊春瞬,并能夠具有機房容災柴信、集群擴展等必不可少的能力,在1.0.0正式支持AP和CP兩種一致性協議并存宽气。1.0.0重構了數據的讀寫和同步邏輯随常,將與業(yè)務相關的CRUD與底層的一致性同步邏輯進行了分層隔離。然后將業(yè)務的讀寫(主要是寫萄涯,因為讀會直接使用業(yè)務層的緩存)抽象為Nacos定義的數據類型绪氛,調用一致性服務進行數據同步。在決定使用CP還是AP一致性時涝影,使用一個代理枣察,通過可控制的規(guī)則進行轉發(fā)。
目前的一致性協議實現燃逻,一個是基于簡化的Raft的CP一致性序目,一個是基于自研協議Distro的AP一致性。Raft協議不必多言伯襟,基于Leader進行寫入猿涨,其CP也并不是嚴格的,只是能保證一半所見一致姆怪,以及數據的丟失概率較小叛赚。Distro協議則是參考了內部ConfigServer和開源Eureka,在不借助第三方存儲的情況下稽揭,實現基本大同小異俺附。Distro重點是做了一些邏輯的優(yōu)化和性能的調優(yōu)。
圖5 Nacos一致性協議
負載均衡
負載均衡嚴格的來說淀衣,并不算是傳統(tǒng)注冊中心的功能昙读。一般來說服務發(fā)現的完整流程應該是先從注冊中心獲取到服務的實例列表,然后再根據自身的需求膨桥,來選擇其中的部分實例或者按照一定的流量分配機制來訪問不同的服務提供者蛮浑,因此注冊中心本身一般不限定服務消費者的訪問策略唠叛。Eureka、Zookeeper包括Consul沮稚,本身都沒有去實現可配置及可擴展的負載均衡機制艺沼,Eureka的負載均衡是由ribbon來完成的,而Consul則是由Fabio做負載均衡蕴掏。
圖6 客戶端側負載均衡
在阿里巴巴集團內部障般,卻是使用的相反的思路。服務消費者往往并不關心所訪問的服務提供者的負載均衡盛杰,它們只關心以最高效和正確的訪問服務提供者的服務挽荡。而服務提供者,則非常關注自身被訪問的流量的調配即供,這其中的第一個原因是定拟,阿里巴巴集團內部服務訪問流量巨大,稍有不慎就會導致流量異常壓垮服務提供者的服務逗嫡。因此服務提供者需要能夠完全掌控服務的流量調配青自,并可以動態(tài)調整。
服務端的負載均衡驱证,給服務提供者更強的流量控制權延窜,但是無法滿足不同的消費者希望使用不同負載均衡策略的需求。而不同負載均衡策略的場景抹锄,確實是存在的逆瑞。而客戶端的負載均衡則提供了這種靈活性,并對用戶擴展提供更加友好的支持祈远。但是客戶端負載均衡策略如果配置不當呆万,可能會導致服務提供者出現熱點商源,或者壓根就拿不到任何服務提供者车份。
圖7 服務端側負載均衡
拋開負載均衡到底是在服務提供者實現還是在服務消費者實現,我們看到目前的負載均衡有基于權重牡彻、服務提供者負載扫沼、響應時間、標簽等策略庄吼。其中Ribbon設計的客戶端負載均衡機制缎除,主要是選擇合適現有的IRule、ServerListFilter等接口實現总寻,或者自己繼承這些接口器罐,實現自己的過濾邏輯。這里Ribbon采用的是兩步負載均衡渐行,第一步是先過濾掉不會采用的服務提供者實例轰坊,第二步是在過濾后的服務提供者實例里铸董,實施負載均衡策略。Ribbon內置的幾種負載均衡策略功能還是比較強大的肴沫,同時又因為允許用戶去擴展粟害,這可以說是一種比較好的設計。
基于標簽的負載均衡策略可以做到非常靈活颤芬,Kubernetes和Fabio都已經將標簽運用到了對資源的過濾中悲幅,使用標簽幾乎可以實現任意比例和權重的服務流量調配。但是標簽本身需要單獨的存儲以及讀寫功能站蝠,不管是放在注冊中心本身或者對接第三方的CMDB汰具。
在Nacos 0.7.0版本中,我們除了提供基于健康檢查和權重的負載均衡方式外菱魔,還新提供了基于第三方CMDB的標簽負載均衡器郁副,具體可以參考CMDB功能介紹文章。使用基于標簽的負載均衡器豌习,目前可以實現同標簽優(yōu)先訪問的流量調度策略存谎,實際的應用場景中,可以用來實現服務的就近訪問肥隆,當您的服務部署在多個地域時既荚,這非常有用。使用這個標簽負載均衡器栋艳,可以支持非常多的場景恰聘,這不是本文要詳細介紹的。雖然目前Nacos里支持的標簽表達式并不豐富吸占,不過我們會逐步擴展它支持的語法晴叨。除此以外,Nacos定義了Selector矾屯,作為負載均衡的統(tǒng)一抽象兼蕊。關于Selector,由于篇幅關系件蚕,我們會有單獨的文章進行介紹孙技。
理想的負載均衡實現應該是什么樣的呢?不同的人會有不同的答案排作。Nacos試圖做的是將服務端負載均衡與客戶端負載均衡通過某種機制結合起來牵啦,提供用戶擴展性,并給予用戶充分的自主選擇權和輕便的使用方式妄痪。負載均衡是一個很大的話題哈雏,當我們在關注注冊中心提供的負載均衡策略時,需要注意該注冊中心是否有我需要的負載均衡方式,使用方式是否復雜裳瘪。如果沒有履因,那么是否允許我方便的擴展來實現我需求的負載均衡策略。
健康檢查
Zookeeper和Eureka都實現了一種TTL的機制盹愚,就是如果客戶端在一定時間內沒有向注冊中心發(fā)送心跳栅迄,則會將這個客戶端摘除。Eureka做的更好的一點在于它允許在注冊服務的時候皆怕,自定義檢查自身狀態(tài)的健康檢查方法毅舆。這在服務實例能夠保持心跳上報的場景下,是一種比較好的體驗愈腾,在Dubbo和SpringCloud這兩大體系內憋活,也被培養(yǎng)成用戶心智上的默認行為。Nacos也支持這種TTL機制虱黄,不過這與ConfigServer在阿里巴巴內部的機制又有一些區(qū)別悦即。Nacos目前支持臨時實例使用心跳上報方式維持活性,發(fā)送心跳的周期默認是5秒橱乱,Nacos服務端會在15秒沒收到心跳后將實例設置為不健康辜梳,在30秒沒收到心跳時將這個臨時實例摘除。
不過正如前文所說泳叠,有一些服務無法上報心跳作瞄,但是可以提供一個檢測接口,由外部去探測危纫。這樣的服務也是廣泛存在的宗挥,而且以我們的經驗,這些服務對服務發(fā)現和負載均衡的需求同樣強烈种蝶。服務端健康檢查最常見的方式是TCP端口探測和HTTP接口返回碼探測契耿,這兩種探測方式因為其協議的通用性可以支持絕大多數的健康檢查場景。在其他一些特殊的場景中螃征,可能還需要執(zhí)行特殊的接口才能判斷服務是否可用搪桂。例如部署了數據庫的主備,數據庫的主備可能會在某些情況下切換会傲,需要通過服務名對外提供訪問锅棕,保證當前訪問的庫是主庫。此時的健康檢查接口淌山,可能就是一個檢查數據庫是否是主庫的MYSQL命令了。
客戶端健康檢查和服務端健康檢查有一些不同的關注點顾瞻∑靡桑客戶端健康檢查主要關注客戶端上報心跳的方式、服務端摘除不健康客戶端的機制荷荤。而服務端健康檢查退渗,則關注探測客戶端的方式移稳、靈敏度及設置客戶端健康狀態(tài)的機制。從實現復雜性來說会油,服務端探測肯定是要更加復雜的个粱,因為需要服務端根據注冊服務配置的健康檢查方式,去執(zhí)行相應的接口翻翩,判斷相應的返回結果都许,并做好重試機制和線程池的管理。這與客戶端探測嫂冻,只需要等待心跳胶征,然后刷新TTL是不一樣的。同時服務端健康檢查無法摘除不健康實例桨仿,這意味著只要注冊過的服務實例睛低,如果不調用接口主動注銷,這些服務實例都需要去維持健康檢查的探測任務服傍,而客戶端則可以隨時摘除不健康實例钱雷,減輕服務端的壓力。
圖8 Nacos的健康檢查
Nacos既支持客戶端的健康檢查吹零,也支持服務端的健康檢查急波,同一個服務可以切換健康檢查模式。我們認為這種健康檢查方式的多樣性非常重要瘪校,這樣可以支持各種類型的服務澄暮,讓這些服務都可以使用到Nacos的負載均衡能力。Nacos下一步要做的是實現健康檢查方式的用戶擴展機制阱扬,不管是服務端探測還是客戶端探測泣懊。這樣可以支持用戶傳入一條業(yè)務語義的請求,然后由Nacos去執(zhí)行麻惶,做到健康檢查的定制馍刮。
性能與容量
雖然大部分用戶用到的性能不高,但是他們仍然希望選用的產品的性能越高越好窃蹋。影響讀寫性能的因素很多:一致性協議卡啰、機器的配置、集群的規(guī)模警没、存量數據的規(guī)模匈辱、數據結構及讀寫邏輯的設計等等。在服務發(fā)現的場景中杀迹,我們認為讀寫性能都是非常關鍵的亡脸,但是并非性能越高就越好,因為追求性能往往需要其他方面做出犧牲。Zookeeper在寫性能上似乎能達到上萬的TPS浅碾,這得益于Zookeeper精巧的設計大州,不過這顯然是因為有一系列的前提存在。首先Zookeeper的寫邏輯就是進行K-V的寫入垂谢,內部沒有聚合厦画;其次Zookeeper舍棄了服務發(fā)現的基本功能如健康檢查、友好的查詢接口滥朱,它在支持這些功能的時候根暑,顯然需要增加一些邏輯,甚至棄用現有的數據結構焚虱;最后购裙,Paxos協議本身就限制了Zookeeper集群的規(guī)模,3鹃栽、5個節(jié)點是不能應對大規(guī)模的服務訂閱和查詢的躏率。
在對容量的評估時,不僅要針對企業(yè)現有的服務規(guī)模進行評估民鼓,也要對未來3到5年的擴展規(guī)模進行預測薇芝。阿里巴巴的中間件在內部支撐著集團百萬級別服務實例,在容量上遇到的挑戰(zhàn)可以說不會小于任何互聯網公司丰嘉。這個容量不僅僅意味著整體注冊的實例數夯到,也同時包含單個服務的實例數、整體的訂閱者的數目以及查詢的QPS等饮亏。Nacos在內部淘汰Zookeeper和Eureka的過程中耍贾,容量是一個非常重要的因素。
Zookeeper的容量路幸,從存儲節(jié)點數來說荐开,可以達到百萬級別。不過如上面所說简肴,這并不代表容量的全部晃听,當大量的實例上下線時,Zookeeper的表現并不穩(wěn)定砰识,同時在推送機制上的缺陷能扒,會引起客戶端的資源占用上升,從而性能急劇下降辫狼。
Eureka在服務實例規(guī)模在5000左右的時候莽龟,就已經出現服務不可用的問題禁炒,甚至在壓測的過程中涕癣,如果并發(fā)的線程數過高,就會造成Eureka crash互墓。不過如果服務規(guī)模在1000上下,幾乎目前所有的注冊中心都可以滿足浑劳。畢竟我們看到Eureka作為SpringCloud的注冊中心蚕愤,在國內也沒有看到很廣泛的對于容量或者性能的問題報告。
Nacos在開源版本中瀑粥,服務實例注冊的支撐量約為100萬挣跋,服務的數量可以達到10萬以上。在實際的部署環(huán)境中狞换,這個數字還會因為機器避咆、網絡的配置與JVM參數的不同,可能會有所差別修噪。圖9展示了Nacos在使用1.0.0版本進行壓力測試后的結果總結查库,針對容量、并發(fā)黄琼、擴展性和延時等進行了測試和統(tǒng)計樊销。
圖9 Nacos性能與容量報告
完整的測試報告可以參考Nacos官網:
https://nacos.io/en-us/docs/nacos-naming-benchmark.html
https://nacos.io/en-us/docs/nacos-config-benchmark.html
易用性
易用性也是用戶比較關注的一塊內容。產品雖然可以在功能特性或者性能上做到非常先進脏款,但是如果用戶的使用成本極高围苫,也會讓用戶望而卻步。易用性包括多方面的工作撤师,例如API和客戶端的接入是否簡單剂府,文檔是否齊全易懂,控制臺界面是否完善等剃盾。對于開源產品來說腺占,還有一塊是社區(qū)是否活躍。在比較Nacos痒谴、Eureka和Zookeeper在易用性上的表現時衰伯,我們誠邀社區(qū)的用戶進行全方位的反饋,因為畢竟在阿里巴巴集團內部闰歪,我們對Eureka嚎研、Zookeeper的使用場景是有限的。從我們使用的經驗和調研來看库倘,Zookeeper的易用性是比較差的临扮,Zookeeper的客戶端使用比較復雜,沒有針對服務發(fā)現的模型設計以及相應的API封裝教翩,需要依賴方自己處理杆勇。對多語言的支持也不太好,同時沒有比較好用的控制臺進行運維管理饱亿。
Eureka和Nacos相比較Zookeeper而言蚜退,已經改善很多闰靴,這兩個產品有針對服務注冊與發(fā)現的客戶端,也有基于SpringCloud體系的starter钻注,幫助用戶以非常低的成本無感知的做到服務注冊與發(fā)現蚂且。同時還暴露標準的HTTP接口,支持多語言和跨平臺訪問幅恋。Eureka和Nacos都提供官方的控制臺來查詢服務注冊情況杏死。不過隨著Eureka 2.0宣布停止開發(fā),Eureka在針對用戶使用上的優(yōu)化后續(xù)應該不會再有比較大的投入捆交,而Nacos目前依然在建設中淑翼,除了目前支持的易用性特性以外,后續(xù)還會繼續(xù)增強控制臺的能力品追,增加控制臺登錄和權限的管控玄括,監(jiān)控體系和Metrics的暴露,持續(xù)通過官網等渠道完善使用文檔肉瓦,多語言SDK的開發(fā)等遭京。
從社區(qū)活躍度的角度來看,目前由于Zookeeper和Eureka的存量用戶較多风宁,很多教程以及問題排查都可以在社區(qū)搜索到洁墙,這方面新開源的Nacos還需要隨著時間繼續(xù)沉淀。
集群擴展性
集群擴展性和集群容量以及讀寫性能關系緊密戒财。當使用一個比較小的集群規(guī)模就可以支撐遠高于現有數量的服務注冊及訪問時热监,集群的擴展能力暫時就不會那么重要。從協議的層面上來說饮寞,Zookeeper使用的ZAB協議孝扛,由于是單點寫,在集群擴展性上不具備優(yōu)勢幽崩。Eureka在協議上來說理論上可以擴展到很大規(guī)模苦始,因為都是點對點的數據同步,但是從我們對Eureka的運維經驗來看慌申,Eureka集群在擴容之后陌选,性能上有很大問題。
集群擴展性的另一個方面是多地域部署和容災的支持蹄溉。當講究集群的高可用和穩(wěn)定性以及網絡上的跨地域延遲要求能夠在每個地域都部署集群的時候咨油,我們現有的方案有多機房容災、異地多活柒爵、多數據中心等役电。
圖10 Nacos的多機房部署和容災
首先是雙機房容災,基于Leader寫的協議不做改造是無法支持的棉胀,這意味著Zookeeper不能在沒有人工干預的情況下做到雙機房容災法瑟。在單機房斷網情況下冀膝,使機房內服務可用并不難,難的是如何在斷網恢復后做數據聚合霎挟,Zookeeper的單點寫模式就會有斷網恢復后的數據對賬問題窝剖。Eureka的部署模式天然支持多機房容災,因為Eureka采用的是純臨時實例的注冊模式:不持久化氓扛、所有數據都可以通過客戶端心跳上報進行補償枯芬。上面說到论笔,臨時實例和持久化實例都有它的應用場景采郎,為了能夠兼容這兩種場景,Nacos支持兩種模式的部署狂魔,一種是和Eureka一樣的AP協議的部署蒜埋,這種模式只支持臨時實例,可以完美替代當前的Zookeeper最楷、Eureka整份,并支持機房容災。另一種是支持持久化實例的CP模式籽孙,這種情況下不支持雙機房容災烈评。
在談到異地多活時,很巧的是犯建,很多業(yè)務組件的異地多活正是依靠服務注冊中心和配置中心來實現的讲冠,這其中包含流量的調度和集群的訪問規(guī)則的修改等。機房容災是異地多活的一部分适瓦,但是要讓業(yè)務能夠在訪問服務注冊中心時竿开,動態(tài)調整訪問的集群節(jié)點,這需要第三方的組件來做路由玻熙。異地多活往往是一個包含所有產品線的總體方案否彩,很難說單個產品是否支持異地多活。
多數據中心其實也算是異地多活的一部分嗦随。從單個產品的維度上列荔,Zookeeper和Eureka沒有給出官方的多數據中心方案。Nacos基于阿里巴巴內部的使用經驗枚尼,提供的解決方案是才有Nacos-Sync組件來做數據中心之間的數據同步贴浙,這意味著每個數據中心的Nacos集群都會有多個數據中心的全量數據。Nacos-Sync是Nacos生態(tài)組件里的重要一環(huán)姑原,不僅會承擔Nacos集群與Nacos集群之間的數據同步悬而,也會承擔Nacos集群與Eureka、Zookeeper锭汛、Kubernetes及Consul之間的數據同步笨奠。
圖11 Nacos的多數據中心方案
用戶擴展性
在框架的設計中袭蝗,擴展性是一個重要的設計原則。Spring般婆、Dubbo到腥、Ribbon等框架都在用戶擴展性上做了比較好的設計。這些框架的擴展性往往由面向接口及動態(tài)類加載等技術蔚袍,來運行用戶擴展約定的接口乡范,實現用戶自定義的邏輯。在Server的設計中啤咽,用戶擴展是比較審慎的晋辆。因為用戶擴展代碼的引入,可能會影響原有Server服務的可用性宇整,同時如果出問題瓶佳,排查的難度也是比較大的。設計良好的SPI是可能的鳞青,但是由此帶來的穩(wěn)定性和運維的風險是需要仔細考慮的霸饲。在開源軟件中,往往通過直接貢獻代碼的方式來實現用戶擴展臂拓,好的擴展會被很多人不停的更新和維護厚脉,這也是一種比較好的開發(fā)模式。Zookeeper和Eureka目前Server端都不支持用戶擴展胶惰,一個支持用戶擴展的服務發(fā)現產品是CoreDNS傻工。CoreDNS整體架構就是通過插件來串聯起來的,通過將插件代碼以約定的方式放到CoreDNS工程下童番,重新構建就可以將插件添加到CoreDNS整體功能鏈路的一環(huán)中精钮。
那么這樣的擴展性是否是有必要的呢?舉一個上文提到過的例子剃斧,假如要添加一種新的健康檢查方式轨香,連接數據庫執(zhí)行一條MySQL命令,通常的方式是在代碼里增加MySQL類型的健康檢查方法幼东、構建臂容、測試然后最終發(fā)布。但是如果允許用戶上傳一個jar包放到Server部署目錄下的某個位置根蟹,Server就會自動掃描并識別到這張新的健康檢查方式呢脓杉?這樣不僅更酷,也讓整個擴展的流程與Server的代碼解耦简逮,變得非常簡單球散。所以對于系統(tǒng)的一些功能,如果能夠通過精心的設計開放給用戶在運行時去擴展散庶,那么為什么不做呢蕉堰?畢竟增加擴展的支持并不會讓原有的功能有任何損失凌净。
所有產品都應該盡量支持用戶運行時擴展,這需要Server端SPI機制設計的足夠健壯和容錯屋讶。Nacos在這方面已經開放了對第三方CMDB的擴展支持冰寻,后續(xù)很快會開放健康檢查及負載均衡等核心功能的用戶擴展。目的就是為了能夠以一種解耦的方式支持用戶各種各樣的需求皿渗。
尾聲
本文并沒有把完整介紹Nacos的所有功能斩芭,包括Nacos支持的DNS協議,打自定義標等能力乐疆。Consul也并沒有在本文做重點比較划乖,因為Consul實際上是和Nacos比較相似的產品,雖然Consul目前的主要發(fā)展方向放在了Service Mesh诀拭,但是Consul最初支持的服務發(fā)現和配置管理迁筛,也是Nacos的兩大功能。與Consul的詳細比較將會通過另外一篇文章單獨介紹耕挨,雖然Nacos在Consul之后以與之相似的部署架構開源,但這并不意味著Nacos在功能和架構上也模仿Consul尉桩,Nacos的架構和功能是由阿里巴巴內部十年的運行演進經驗得來筒占,所以二者的比較也一定會讓大家更加了解他們的定位和演進方向是完全不一樣的。
為了能讓大家對注冊中心產品整體的差異有一個快速的總覽蜘犁,我們制作了下面這個表格:
Nacos已經在4月10號發(fā)布GA版本翰苫,后續(xù)將會以和社區(qū)共建的方式,持續(xù)輸出新的功能这橙,在服務發(fā)現和配置管理這兩大領域繼續(xù)深耕奏窑,期待與大家一起建設出最好用的服務發(fā)現和配置管理平臺。
|