盤點一下常用的注冊中心
上圖基本表達了注冊中心的交互過程, 體現出三種角色之間關系:
- 服務提供者 Service Provider (Server):
- 服務啟動后向RegistryCenter注冊自己的一個實例
- 定期向RegistryCenter發送心跳(heartbeat), 證明自己還能苟一會
- 服務關閉時向RegistryCenter發起注銷
- 服務消費者 Service Consumer(Client):
- 服務啟動后RegistryCenter訂閱所需要使用的服務(Server), 並緩存到實例列表中
- 向對應服務(Server)發起調用時,從內存中的該服務的實例列表選擇一個,進行遠程調用.
- 服務關閉時向RegistryCenter取消訂閱
- 注冊中心 Service Registry Center:
- Server超過一定時間未心跳時,從服務的實例列表移除.
- 服務的實例列表發生變化(新增或者移除)時,通知訂閱該服務的 Consumer,從而讓 Consumer 能夠刷新本地緩存. 有些 注冊中心不提供這項功能, 例如Eureka,二手Client 定期輪詢更新本地緩存
大多數情況下一個服務可能既是Client又是 Consumer
CAP
CAP理論是分布式架構中重要理論
- 一致性(Consistency) (所有節點在同一時間具有相同的數據)
- 可用性(Availability) (保證每個請求不管成功或者失敗都有響應)
- 分隔容忍(Partition tolerance) (系統中任意信息的丟失或失敗不會影響系統的繼續運作)
由於C與A的特性無法共存.CAP 不可能都取,只能取其中2個,要么AP要么CP
注冊中心的品牌
說到這個, 先扯一下服務發現, 當我們的服務從單機走向社會的時候, 就產生了服務發現.
一開始服務發現是通DNS協議實現的, 就是網路IP協議, 通過DNS + LVS基本就實現了http形式的服務發現, 這個時候IP通常是配置在LVS.之后大家開始玩起RPC服務, 服務的部署開始頻繁.為了實現動態上下線, 整出來注冊中心 目的其實就是推送IP列.
zookeeper
Zoopkeeper 在國內很長一段時間都是注冊中心一哥.大部分是因為Dubbo 在國能的盛行.
Eureka
Eureka是一家在線影片租賃提供商Netflix開源的, 這家公司的理念還是滿超前的.
Netflix玩的是一種流媒體服務. 愛、死亡與機器人, 怪奇物語,紙牌屋,黑鏡.. 這些耳熟能詳的美劇都是旗下的作品. Netflix一直以來的商業模式其實就是眾籌, 用戶用更低的產品看電視劇. 到現在開始踏足原創劇集時代,這才是Netflix從諸多電視巨頭中突圍的原因.非常的頂.
很多Spring Cloud的組件都是Netflix做的, 這是Netflix的微服務生態.方便Spring開發人員構建微服務基礎框架.而Eureka則借着微服務概念的流行,與SpringCloud生態的深度結合,也獲取了大量的粉絲.
Nacos
Nacos 是阿里開源的, 功能其實也很多, 服務注冊, 配置管理, 動態 DNS 服務, 元數據管理
注冊中心的較量
Nacos | Eureka | Consul | zookeeper | |
---|---|---|---|---|
數據一致性 | AP/CP | AP | CP | CP |
健康檢查 | TCP/HTTP/MySql/ClientBeat | ClientBeat | TCP/HTTP/grpc/Cmd | Keep Alive |
負載均衡策略 | 權重/metadata/Selector | Ribbon | Fabio | - |
雪崩保護 | 有 | 有 | 無 | 無 |
容量 | 100w | 5000 | 百萬級 | 百萬級 |
自動注銷實例 | √ | √ | × | √ |
訪問協議 | HTTP/DNS | HTTP | HTTP/DNS | TCP |
監聽支持 | √ | √ | √ | √ |
多數據中心 | √ | √ | √ | × |
跨注冊中心同步 | √ | × | √ | × |
Spring Cloud集成 | √ | √ | √ | × |
Dubbo集成 | √ | × | × | √ |
K8s集成 | √ | × | √ | × |
數據一致性
數據一致性一直是分布式系統的熱點, 目前基本歸為兩派:
- AP: 對等部署的多寫一致性
- CP: 基於leader的非對等部署的單點寫一致性
可以通過心跳檢測來舉個例子, 強一致性注冊中心,服務節點不會發送心跳,因為第一次注冊的時候就必須保證數據不會丟失,而如果服務節點能發送心跳第一次注冊的成功與否就會顯得不那么重要(當然也非常重要,這里指的是允許出現失敗)
這也是Eureka為什么采用自定義的Renew機制的原因,而不是Paxos協議(據說拿過圖靈獎).
對於dubbo來說其實采用Renew機制更好, 主要是因為注冊到zookeeper上是臨時節點,還允許服務下線,發送心跳到zookeeper上來續約服務節點.zookeeper保證了一致性,就確實服務的高可用,導致機房容災能力的確實.
Nacos支持AP和CP兩種協議如圖所示.在這點設計上有個騷操作, 就是把業務相關邏輯和底層同步邏輯分層,將業務讀寫抽象為Nacos定義為的[數據模型](# 數據模型).通過代理, 根據一定的規則進行轉發.
數據模型
注冊中心最核心的數據就是服務名和IP地址,zookeeper是一個樹形k-v的數據結構,理論上滿足各種語境的數據.而Eureka和Consul做到實例級別的數據擴展.滿足最根本需求.Nacos的數據模型相對復雜.如圖所示:
Nacos考慮的是數據的隔離模型, 並提供了四種.作為一個共享服務的組件,需要能夠在各種環境保證數據的隔離和安全,這點在龐大的業務場景中非常常見.
上面說的業務邏輯和同步邏輯其實指的就是臨時實例和持久化實例.在定義上區分臨時實例和持久化實例的關鍵是健康檢查的方式, 臨時實例使用客戶端上報模式, 而持久化實例使用服務端反向探測模式.臨時實例需要能夠自動摘除不健康實例,而且無需持久化存儲實例.持久化實例使用服務端探測的健康檢查方式,因為客戶端不會上報心跳,那么自然就不能去自動摘除下線的實例.
一些基礎的組件例如數據庫、緩存等,這些往往不能上報心跳,這種類型的服務在注冊時,就需要作為持久化實例注冊.而上層的業務服務
健康檢查
大多通過心跳檢測實現,如果客戶端一定時間內沒發送心跳,服務節點會被注銷.這種機制被稱為TTL. Eureka允許自定義檢查服務本身的方法.不同注冊中心檢查機制不同, Nacos是5秒一個周期,15秒沒收到心跳,服務被標記為不健康, 30秒沒收到則注銷服務.
另外, client服務和server服務又有不同:
-
client健康檢查關注上報心跳的方式,注銷不健康服務的機制.
-
server健康檢查關注的是探測服務端的方式,靈敏度以及設置server服務健康狀態的機制.
一般來說注冊過的server服務實例如果不調用結構主動注銷,就意味着維持健康檢查的探測任務, 而client服務實例則可以隨時注銷不健康的實例,減輕服務端的壓力.
負載均衡
講道理,負載均衡不是注冊中心的傳統藝能.一般來說,服務發現的流程就是從注冊中心獲取實例列表, 然后選擇自身所需符合規則被分配的服務提供者,注冊中心不會限制消費者的訪問策略.
Eureka,zookeeper,Consul基本都是這樣.Eureka的負載均衡是由Ribbon負責的, Consul的負載均衡是由Fabio完成的.
目前的負載均衡有基於權重、服務提供者負載、響應時間、標簽等策略.
Ribbon設計的客戶端負載均衡機制主要是選擇合適現有的IRule、ServerListFilter等接口實現,兩步實現負載均衡:
- 過濾掉不會采用的服務提供者實例
- 在被過濾后的服務列表中進行負載均衡
Fabio是基於標簽做負載均衡, 這點和kubernetes類似, 都是將標簽運到資源的過濾上,實現標簽的比例和權重的負載均衡.
Nacos除了提供權重的負載均衡之外, 還提供了CMDB的標簽負載均衡.實現同標簽優先訪問的流量調度策略.如果服務部署在多個不同的地區, CMDB的負載將會起到不錯的效果.充分均勻的分配流量.
集群擴展性
Zookeeper基於leader的非對等部署的單點寫一致性,無法做到自動多機房容災
Eureka的部署模式天然支持多機房容災
Nacos支持兩種模式的部署,一種是和Eureka一樣的AP協議的部署,這種模式只支持臨時實例,可以完美替代當前的Zookeeper、Eureka,並支持機房容災.另一種是支持持久化實例的CP模式,這種情況下不支持雙機房容災.
機房容災是異地多活的一部分,讓業務能夠在訪問服務注冊中心時,動態調整訪問的集群節點,需要第三方做路由.
多數據中心其實也算是異地多活的一部分. Zookeeper和Eureka沒有官方的數據中心方案.Nacos有Nacos-Sync組件來做數據中心之間的數據同步,不僅可以在Nacos之間同步, 還可以實現Nacos在zookeeper,k8s.Consul和Eureka的數據同步, 實現生態大和諧.
總結
這篇文章盤點注冊中心各自的特性
- Nacos大而全
- Eureka 小而美
- Consul其實跟Nacos比較相似.
- zookeeper 性能好難擴展
, 歡迎關注,評論,點贊, 轉發~