SpringCloud和Dubbo的服務發現機制的區別
SpringCloud和Dubbo都是當下流行的RPC框架,各自都集成了服務發現和治理元件。SpringCloud用Eureka,Dubbo用Zookeeper,這篇部落格就將將這兩個元件在各自系統中的作用機制的區別。
1.註冊的服務的區別
Dubbo是基於java介面及Hession2序列化的來實現傳輸的,Provider對外暴露介面,Consumer根據介面的規則呼叫。也就是Provider向Zookeeper註冊的是介面資訊,Consumer從Zookeeper發現的是介面的資訊,通過介面的name,group,version來匹配呼叫。Consumer只關注介面是否匹配,而對此介面屬於什麼應用不關心。當然介面的註冊資訊裡會包含應用的ip,hostname等。
SpringCloud的服務發現是基於Http協議來實現的,Provider對外暴露的是應用資訊,比如應用名稱,ip地址等等,Consumer發現的是應用的資訊,當呼叫的時候隨機選擇一個Provider的IP地址,應用名稱,然後依據Http協議傳送請求。Consumer關注的是應用名稱,根據應用名稱來決定呼叫的是哪個服務叢集,然後對此名稱對應的服務叢集做負載均衡。Provider接受到請求後,根據內建的SpringMVC來匹配路由處理請求。
2 . Server叢集服務資訊同步的區別
Dubbo使用Zookeeper做服務發現和治理,Zookeeper是一個分散式協調框架,其有很多很實用的功能,服務發現僅僅是其中的一個。Zookeeper基於著名的CAP理論中的C(一致性),P(分割槽可用性)實現,它的ZAB(zookeeper atomic broadcast protocol)協議,保證了叢集裡狀態的一致性。Client的每一個事務操作都由Leader廣播給所有Follower,當超過半數的Follower都返回執行成功後,才執行事務的ack。對於因網路崩潰或者宕機等問題而執行失敗的zookeeper節點,zookeeper會基於zab的崩潰恢復機制來處理,這裡不再講述。每一個操作都需要過半數的zookeeper節點執行成功才確認成功,那麼當zookeeper叢集過半數節點出現問題時,服務發現功能就不可用。
SpringCloud使用Eureka做服務發現和治理,它是一個專門用於服務發現和治理的框架,其基於CAP理論中的A(可用性),P(分割槽可用性)實現。EurekaServer節點間的服務資訊同步是基於非同步Http實現的。每隔Server節點在接收Client的服務請求時,立即處理請求,然後將此次請求的資訊拷貝,封裝成一個Task,存入Queue中。Server初始化時會啟動一個執行緒定期的從TaskQueue中批量提取Task,然後執行。服務同步不保證一定成功,雖然有失敗重試,但超過一定時限後就放棄同步。當然其有一個特性,當服務丟失後,同步的操作返回400,404後會立即將最新的服務資訊同步過去,因此即使中途同步失敗,不會對後續的同步有影響。
3 . 服務更新機制的區別
Dubbo使用Zookeeper做服務發現和治理,訂閱Zookeeper下相應的znode。當節點發生變化,比如有新的元素增加,或者舊的元素移除,Zookeeper會通知所有訂閱此節點的Client,將當前的全量資料同步給各Client,Dubbo里根據最新的資料來做相應處理,移除下線的,初始化新增的。每次更新都同步全量資料。
Eureka在啟動時向Server進行一次全量拉取,獲取所有的可用服務資訊,之後預設情況下都是進行增量拉取。Server會將有變化的服務資訊放在一個Queue裡,Client每次同步時僅獲取增量資訊,根據資訊裡的操作型別,服務資訊來對當前持有的服務做相應的處理,移除下線的,初始化新增的等。每次更新僅同步增量資料,也就是更新的資料。
4 . 服務更新反饋機制的區別
Dubbo訂閱Zookeeper下相應的節點,當節點的狀態發生改變時,Zookeeper會立即反饋訂閱的Client,實時性很高。
Eureka Server在接收到Client的更新操作,或者移除服務資訊時,僅僅會將更新訊息存放入recentlyChangedQueue中,不會主動的反饋其他Client。其他Client只有在拉取服務增量資訊時才會感知到某個服務的更新,延時最大為30S,也就是拉取週期。
5 . 服務資訊回收機制的區別
Dubbo Provider初始化時會建立一個Zookeeper Client,專門用於與Zookeeper叢集互動。維持與叢集間的長連線,定時傳送心跳,維護Zookeeper上自身節點的存在。節點型別是臨時節點,也就是當心跳超時或者長連線斷開時,會立即移除Provider對應的節點。
Dubbo Consumer初始化時也會建立一個Zookeeper Client,專門用於與Zookeeper叢集互動。維持長連線,建立EvenetListener,監聽Provider節點的變動情況。當Provider節點新增或者移除時,Zookeeper會廣播這個事件,然後將此節點的當前值(剩下的所有介面資訊)傳送給那些註冊了此節點監聽器的Client。Consumer獲取到對應Provider節點下的所有介面資訊後,移除已下線的,建立新增的。
Zookeeper對服務資訊的維護實時性和一致性比較高,但也可能因為網路問題或者叢集問題導致服務不可用。
SpringCloud的服務資訊回收僅基於心跳超時,與長連線無關。當心跳超時後,EurekaServer回收服務資訊,然後將此動作同步給其他Server節點。當然可能一個服務資訊會存在多個Server上,多次回收操作的同步具備冪等性。也就是說服務回收只需要通知一個Server節點就可以了,回收動作會通過Server節點傳播開來。EurekaServer能夠回收服務資訊由個重要前提:上一分鐘內正常傳送心跳的服務的比列超過總數的85%,如果因為網路波動等原因造成大量服務的心跳超時,那麼EurekaServer會觸發自我保護機制,放棄回收那些心跳超時的服務資訊。服務發現元件應該優先保證可用性,Consumer能夠發現Provider,即使發現的是非可用的Provider,但因為Conusmer一般具備容錯機制,不會對服務的正常呼叫有太多影響。從這點上看Eureka的服務發現機制要比Zookeeper稍微合理一點的。
6 . 節點性質的區別
Dubbo只有Consumer訂閱Provider節點,也就是Consumer發現Provider節點資訊
Eureka不區分Consumer或者Provider,兩者都統稱為Client,一個Client內可能同時含有Provider,Consumer,Client的是其他所有的Client節點資訊,在呼叫時根據應用名稱來篩選節點
7 . 使用方式的區別
Dubbo使用Zookeeper作為服務發現和治理的元件,所以需要搭建Zookeeper叢集作為依賴。
SpringCloud使用Eureka作為服務發現和治理元件,在Spring應用中整合Eureka還是很簡單的,引入依賴,加個註解,指定叢集Server的serviceUrl,其他的都可以使用預設配置即可,啟動應用,Eureka叢集就搭建好了。同時配合SpringCloudConfg,能夠統一管理Eureka的叢集配置資訊,可以動態的增加或減少EurekaServer的叢集節點。Eurerka會每隔15分鐘根據配置上的叢集資訊重新生成叢集節點,覆蓋之前的。這種機制比Zookeeper要更優秀一些,畢竟Eureka算是Spring生態裡的一環,已經被整合的非常好了,能夠以很多匪夷所思的方式來使用。