CAP是Consistency、Availablity和Partition Tolerance的縮寫。通常的分佈式系統最多知足其中兩條。而Partition Tolerance是分佈式系統的關鍵,所以都會保留此特性。java
Eureka是基於AP原則構建的,而ZooKeeper是基於CP原則構建的。這些能夠從他們的特性中獲得體現。web
ZK有一個Leader,並且在Leader沒法使用的時候經過Paxos(ZAB)算法選舉出一個新的Leader。這個Leader的目的就是保證寫信息的時候只向這個Leader寫入,Leader會同步信息到Followers。這個過程就能夠保證數據的一致性。算法
對比下ZK,Eureka不用選舉一個Leader。每一個Eureka服務器單獨保存服務註冊地址,Eureka也沒有Leader的概念。這也所以產生了沒法保證每一個Eureka服務器都保存一直數據的特性。當Eureka與註冊者心跳沒法保持的時候,依然保存註冊列表的信息很長一段時間。固然了,客戶端中必須用有效的機制屏蔽壞掉的服務器,這個Spring Cloud中的體現是Ribbon。服務器
Eureka由於沒有選舉過程來選舉Leader,所以寫的信息能夠獨立進行。所以有可能出現數據信息不一致的狀況。可是當網絡出現問題的時候,每臺服務器也能夠完成獨立的服務。固然了,一些客戶端的負載平衡和Fail Over機制須要來輔助完成額外的功能。相較之下,ZK由於基於CP原則,能保證很好的數據一致性,可是可用性支持力度不高。而在一個內部系統中,主要是服務的註冊與發現,而不是配置(文件)共享,所以Eureka更適用於內部服務的建設。網絡
著名的CAP理論指出,一個分佈式系統不可能同時知足C(一致性)、A(可用性)和P(分區容錯性)。因爲分區容錯性在是分佈式系統中必需要保證的,所以咱們只能在A和C之間進行權衡。在此Zookeeper保證的是CP, 而Eureka則是AP。分佈式
當向註冊中心查詢服務列表時,咱們能夠容忍註冊中心返回的是幾分鐘之前的註冊信息,但不能接受服務直接down掉不可用。也就是說,服務註冊功能對可用性的要求要高於一致性。可是zk會出現這樣一種狀況,當master節點由於網絡故障與其餘節點失去聯繫時,剩餘節點會從新進行leader選舉。問題在於,選舉leader的時間太長,30 ~ 120s, 且選舉期間整個zk集羣都是不可用的,這就致使在選舉期間註冊服務癱瘓。在雲部署的環境下,因網絡問題使得zk集羣失去master節點是較大機率會發生的事,雖然服務可以最終恢復,可是漫長的選舉時間致使的註冊長期不可用是不能容忍的。性能
Eureka看明白了這一點,所以在設計時就優先保證可用性。Eureka各個節點都是平等的,幾個節點掛掉不會影響正常節點的工做,剩餘的節點依然能夠提供註冊和查詢服務。而Eureka的客戶端在向某個Eureka註冊或時若是發現鏈接失敗,則會自動切換至其它節點,只要有一臺Eureka還在,就能保證註冊服務可用(保證可用性),只不過查到的信息可能不是最新的(不保證強一致性)。除此以外,Eureka還有一種自我保護機制,若是在15分鐘內超過85%的節點都沒有正常的心跳,那麼Eureka就認爲客戶端與註冊中心出現了網絡故障,此時會出現如下幾種狀況:
1. Eureka再也不從註冊列表中移除由於長時間沒收到心跳而應該過時的服務
2. Eureka仍然可以接受新服務的註冊和查詢請求,可是不會被同步到其它節點上(即保證當前節點依然可用)
3. 當網絡穩定時,當前實例新的註冊信息會被同步到其它節點中設計
所以, Eureka能夠很好的應對因網絡故障致使部分節點失去聯繫的狀況,而不會像zookeeper那樣使整個註冊服務癱瘓。開發
Eureka做爲單純的服務註冊中心來講要比zookeeper更加「專業」,由於註冊服務更重要的是可用性,咱們能夠接受短時間內達不到一致性的情況。不過Eureka目前1.X版本的實現是基於servlet的java web應用,它的極限性能確定會受到影響。期待正在開發之中的2.X版本可以從servlet中獨立出來成爲單獨可部署執行的服務。部署