最近在面試的時候,被問到了這個問題,做答的不是很好,在此進行整理和學習,但願可以幫助你們。面試
在瞭解eureka和zookeeper區別以前,咱們先來了解一下這個知識,cap理論。
1998年的加州大學的計算機科學家 Eric Brewer 提出,分佈式有三個指標。Consistency,Availability,Partition tolerance。簡稱即爲CAP。Eric 提出 CAP 不能所有達到,這就是CAP定理。
接下來咱們分別說下cap。緩存
Consistency,一致性的意思。
一致性就是說,咱們讀寫數據必須是一摸同樣的。
好比一條數據,分別存在兩個服務器中,server1和server2。
咱們此時將數據a經過server1修改成數據b。此時若是咱們訪問server1訪問的應該是b。
當咱們訪問server2的時候,若是返回的仍是未修改的a,那麼則不符合一致性,若是返回的是b,則符合數據的一致性。服務器
Availability,可用性的意思。
這個比較好理解,就是說,只要我對服務器,發送請求,服務器必須對我進行相應,保證服務器一直是可用的。網絡
Partition tolerance,分區容錯的意思。
通常來講,分佈式系統是分佈在多個位置的。好比咱們的一臺服務器在北京,一臺在上海。可能因爲天氣等緣由的影響。形成了兩條服務器直接不能互相通訊,數據不能進行同步。這就是分區容錯。咱們認爲,分區容錯是不可避免的。也就是說 P 是必然存在的。架構
由以上咱們得知,P是必然存在的。
若是咱們保證了CP,即一致性與分佈容錯。當咱們經過一個服務器修改數據後,該服務器會向另外一個服務器發送請求,將數據進行同步,但此時,該數據應處於鎖定狀態,不可再次修改,這樣,若是此時咱們想服務器發送請求,則得不到相應,這樣就不能A,高可用。
若是咱們保證了AP,那麼咱們不能對服務器進行鎖定,任什麼時候候都要獲得相應,那麼數據的一致性就很差說了。分佈式
eureka是基於ap的。zookeeper是基於cp的。ide
eureka的架構實現圖以下:
微服務
上圖是來自eureka的官方架構圖,這是基於集羣配置的eureka;學習
服務啓動後向Eureka註冊,Eureka Server會將註冊信息向其餘Eureka Server進行同步,當服務消費者要調用服務提供者,則向服務註冊中心獲取服務提供者地址,而後會將服務提供者地址緩存在本地,下次再調用時,則直接從本地緩存中取,完成一次調用。設計
當服務註冊中心Eureka Server檢測到服務提供者由於宕機、網絡緣由不可用時,則在服務註冊中心將服務置爲DOWN狀態,並把當前服務提供者狀態向訂閱者發佈,訂閱過的服務消費者更新本地緩存。
服務提供者在啓動後,週期性(默認30秒)向Eureka Server發送心跳,以證實當前服務是可用狀態。Eureka Server在必定的時間(默認90秒)未收到客戶端的心跳,則認爲服務宕機,註銷該實例。
在默認配置中,Eureka Server在默認90s沒有獲得客戶端的心跳,則註銷該實例,可是每每由於微服務跨進程調用,網絡通訊每每會面臨着各類問題,好比微服務狀態正常,可是由於網絡分區故障時,Eureka Server註銷服務實例則會讓大部分微服務不可用,這很危險,由於服務明明沒有問題。
爲了解決這個問題,Eureka 有自我保護機制,經過在Eureka Server配置以下參數,可啓動保護機制。
eureka.server.enable-self-preservation=true
它的原理是,當Eureka Server節點在短期內丟失過多的客戶端時(可能發送了網絡故障),那麼這個節點將進入自我保護模式,再也不註銷任何微服務,當網絡故障回覆後,該節點會自動退出自我保護模式。
eureka優先保證可用性。在Eureka平臺中,若是某臺服務器宕機,Eureka不會有相似於ZooKeeper的選舉leader的過程;客戶端請求會自動切換 到新的Eureka節點;當宕機的服務器從新恢復後,Eureka會再次將其歸入到服務器集羣管理之中;而對於它來講,全部要作的無非是同步一些新的服務 註冊信息而已。因此,不再用擔憂有「掉隊」的服務器恢復之後,會從Eureka服務器集羣中剔除出去的風險了。Eureka甚至被設計用來應付範圍更廣 的網絡分割故障,並實現「0」宕機維護需求。當網絡分割故障發生時,每一個Eureka節點,會持續的對外提供服務(注:ZooKeeper不會):接收新 的服務註冊同時將它們提供給下游的服務發現請求。這樣一來,就能夠實如今同一個子網中(same side of partition),新發布的服務仍然能夠被發現與訪問。Eureka各個節點都是平等的,幾個節點掛掉不會影響正常節點的工做,剩餘的節點依然能夠提供註冊和查詢服務。而Eureka的客戶端在向某個Eureka註冊或時若是發現鏈接失敗,則會自動切換至其它節點,只要有一臺Eureka還在,就能保證註冊服務可用(保證可用性),只不過查到的信息可能不是最新的(不保證強一致性)。除此以外,Eureka還有一種自我保護機制,若是在15分鐘內超過85%的節點都沒有正常的心跳,那麼Eureka就認爲客戶端與註冊中心出現了網絡故障,此時會出現如下幾種狀況:
做爲一個分佈式協同服務,ZooKeeper很是好,可是對於Service發現服務來講就不合適了;由於對於Service發現服務來講就算是 返回了包含不實的信息的結果也比什麼都不返回要好;再者,對於Service發現服務而言,寧肯返回某服務5分鐘以前在哪幾個服務器上可用的信息,也不能 由於暫時的網絡故障而找不到可用的服務器,而不返回任何結果。因此說,用ZooKeeper來作Service發現服務是確定錯誤的。
當向註冊中心查詢服務列表時,咱們能夠容忍註冊中心返回的是幾分鐘之前的註冊信息,但不能接受服務直接down掉不可用。也就是說,服務註冊功能對可用性的要求要高於一致性。可是zk會出現這樣一種狀況,當master節點由於網絡故障與其餘節點失去聯繫時,剩餘節點會從新進行leader選舉。問題在於,選舉leader的時間太長,30 ~ 120s, 且選舉期間整個zk集羣都是不可用的,這就致使在選舉期間註冊服務癱瘓。在雲部署的環境下,因網絡問題使得zk集羣失去master節點是較大機率會發生的事,雖然服務可以最終恢復,可是漫長的選舉時間致使的註冊長期不可用是不能容忍的。
Eureka能夠很好的應對因網絡故障致使部分節點失去聯繫的狀況,而不會像zookeeper那樣使整個註冊服務癱瘓。Eureka做爲單純的服務註冊中心來講要比zookeeper更加「專業」,由於註冊服務更重要的是可用性,咱們能夠接受短時間內達不到一致性的情況。