详解Eureka服务注册与发现和Ribbon负载均衡【纯理论实战】
Eureka服務注冊與發現
Eureka簡介
在介紹Eureka前,先說一下CAP原則
CAP原則又稱CAP定理,指的是在一個分布式系統中,Consistency(一致性)、 Availability(可用性)、Partition tolerance(分區容錯性),三者不可兼得,Eureka遵循的事AP原則。
關于Eureka
Eureka是Netflix開發的服務發現框架,本身是一個基于REST的服務,主要用于定位運行在AWS域中的中間層服務,以達到負載均衡和中間層服務故障轉移的目的。SpringCloud將它集成在其子項目spring-cloud-netflix中,以實現SpringCloud的服務發現功能。
SpringCloud 封裝了Netflix公司開發的Eureka模塊來實現服務注冊和發現(請對比Zookeeper)。Eureka Server 作為服務注冊功能的服務器,它是服務注冊中心。而系統中的其他微服務,使用 Eureka 的客戶端連接到 Eureka Server并維持心跳連接。這樣系統的維護人員就可以通過 Eureka Server 來監控系統中各個微服務是否正常運行。SpringCloud 的一些其他模塊(比如Zuul)就可以通過 Eureka Server 來發現系統中的其他微服務,并執行相關的邏輯。
補充:AWS域是什么呢?因為之前沒有接觸過這個概念,所以這里做一個簡單的補充。
AWS云服務在全球不同的地方都有數據中心,比如北美、南美、歐洲和亞洲等。與此對應,根據地理位置我們把某個地區的基礎設施服務集合稱為一個區域。
具體可參考(AWS)
關于Eureka和Dubbo(圖示)
Eureka的兩大組件和三大角色的介紹
Eureka包含兩個組件:Eureka Server和Eureka Client
Eureka Server提供服務注冊服務各個節點啟動后,會在EurekaServer中進行注冊,這樣EurekaServer中的服務注冊表中將會存儲所有可用服務節點的信息,服務節點的信息可以在界面中直觀的看到。
EurekaClient是一個Java客戶端,用于簡化Eureka Server的交互,客戶端同時也具備一個內置的、使用輪詢(round-robin)負載算法的負載均衡器。在應用啟動后,將會向Eureka Server發送心跳(默認周期為30秒)。如果Eureka Server在多個心跳周期內沒有接收到某個節點的心跳,EurekaServer將會從服務注冊表中把這個服務節點移除(默認90秒)。
Eureka三大角色:
Eureka Server:提供服務注冊與發現。
Service Provider:服務提供方,將自身服務注冊到Eureka Server,從而使服務消費者能夠找到。
Service Customer:服務消費方,從Eureka Server上獲取注冊服務列表,從而能夠消費服務。
Eureka的自我保護模式
什么是自我保護模式?
默認情況下,如果EurekaServer在一定時間內沒有接收到某個微服務實例的心跳,EurekaServer將會注銷該實例(默認90秒)。但是當網絡分區故障發生時,微服務與EurekaServer之間無法正常通信,以上行為可能變得非常危險了——因為微服務本身其實是健康的,此時本不應該注銷這個微服務。Eureka通過“自我保護模式”來解決這個問題——當EurekaServer節點在短時間內丟失過多客戶端時(可能發生了網絡分區故障),那么這個節點就會進入自我保護模式。一旦進入該模式,EurekaServer就會保護服務注冊表中的信息,不再刪除服務注冊表中的數據(也就是不會注銷任何微服務)。當網絡故障恢復后,該Eureka Server節點會自動退出自我保護模式。
在自我保護模式中,Eureka Server會保護服務注冊表中的信息,不再注銷任何服務實例。當它收到的心跳數重新恢復到閾值以上時,該Eureka Server節點就會自動退出自我保護模式。它的設計哲學就是寧可保留錯誤的服務注冊信息,也不盲目注銷任何可能健康的服務實例。一句話講解:好死不如賴活著。
綜上,自我保護模式是一種應對網絡異常的安全保護措施。它的架構哲學是寧可同時保留所有微服務(健康的微服務和不健康的微服務都會保留),也不盲目注銷任何健康的微服務。使用自我保護模式,可以讓Eureka集群更加的健壯、穩定。
在Spring Cloud中,可以使用eureka.server.enable-self-preservation = false 禁用自我保護模式。
一個服務消費者的目標是什么?
構建一個服務消費者,它主要完成兩個目標,發現服務以及消費服務。
發現服務任務由Eureka客戶端完成,而服務消費任務由Ribbon完成。Ribbon是基于HTTP和TCP的客戶端負載均衡器,它可以在客戶端中配置ribbonServerList服務端列表去輪詢訪問以達到均衡負載的作用。當Ribbon和Eureka聯合使用時,Ribbon的服務清單實例ribbonServerList會被DiscoveryEnabledNIWSServerlist重寫,擴展成從Eureka注冊中心獲取服務端列表。同時它也會用NIWSDiscoveryPing來取代IPing,它將職責委托給Eureka來確定服務端是否已經啟動。
關于@EnableEurekaClient 與@EnableDiscoveryClient這兩個注解
首先這個兩個注解都可以實現服務發現的功能,在spring cloud中discovery service有許多種實現(eureka、consul、zookeeper等等)
@EnableEurekaClient基于spring-cloud-netflix。服務采用eureka作為注冊中心,使用場景較為單一。
@EnableDiscoveryClient基于spring-cloud-commons。服務采用其他注冊中心。
作為注冊中心Eureka比zookeeper好在哪里?
作為服務注冊中心,Eureka比Zookeeper好在哪里?著名的CAP理論指出,一個分布式系統不可能同時滿足C(一致性)、A(可用性)和P(分區容錯性)。由于分區容錯性P在是分布式系統中必須要保證的,因此我們只能在A和C之間進行權衡。因此Zookeeper保證的是CP,Eureka則是AP。
Zookeeper保證CP
當向注冊中心查詢服務列表時,我們可以容忍注冊中心返回的是幾分鐘以前的注冊信息,但不能接受服務直接down掉不可用。也就是說,服務注冊功能對可用性的要求要高于一致性。但是zk會出現這樣一種情況,當master節點因為網絡故障與其他節點失去聯系時,剩余節點會重新進行leader選舉。問題在于,選舉leader的時間太長,30 ~ 120s, 且選舉期間整個zk集群都是不可用的,這就導致在選舉期間注冊服務癱瘓。在云部署的環境下,因網絡問題使得zk集群失去master節點是較大概率會發生的事,雖然服務能夠最終恢復,但是漫長的選舉時間導致的注冊長期不可用是不能容忍的。
Eureka保證AP
Eureka看明白了這一點,因此在設計時就優先保證可用性。Eureka各個節點都是平等的,幾個節點掛掉不會影響正常節點的工作,剩余的節點依然可以提供注冊和查詢服務。而Eureka的客戶端在向某個Eureka注冊時如果發現連接失敗,則會自動切換至其它節點,只要有一臺Eureka還在,就能保證注冊服務可用(保證可用性),只不過查到的信息可能不是最新的(不保證強一致性)。除此之外,Eureka還有一種自我保護機制,如果在15分鐘內超過85%的節點都沒有正常的心跳,那么Eureka就認為客戶端與注冊中心出現了網絡故障,此時會出現以下幾種情況:
Eureka集群
集群原理
基本原理
上圖是來自eureka的官方架構圖,這是基于集群配置的eureka;
- 處于不同節點的eureka通過Replicate(復制)進行數據同步
- Application Service為服務提供者
- Application Client為服務消費者
- Make Remote Call完成一次服務調用
服務啟動后向Eureka注冊,Eureka Server會將注冊信息向其他Eureka Server進行同步,當服務消費者要調用服務提供者,則向服務注冊中心獲取服務提供者地址,然后會將服務提供者地址緩存在本地,下次再調用時,則直接從本地緩存中取,完成一次調用。
當服務注冊中心Eureka Server檢測到服務提供者因為宕機、網絡原因不可用時,則在服務注冊中心將服務置為DOWN狀態,并把當前服務提供者狀態向訂閱者發布,訂閱過的服務消費者更新本地緩存。
服務提供者在啟動后,周期性(默認30秒)向Eureka Server發送心跳,以證明當前服務是可用狀態。Eureka Server在一定的時間(默認90秒)未收到客戶端的心跳,則認為服務宕機,注銷該實例。
補充:
Ribbon負載均衡
什么是負載均衡
LB,即負載均衡(Load Balance),在微服務或分布式集群中經常用的一種應用。
負載均衡簡單的說就是將用戶的請求平攤的分配到多個服務上,從而達到系統的HA。
常見的負載均衡有軟件Nginx,LVS,硬件 F5等。
相應的在中間件,例如:dubbo和SpringCloud中均給我們提供了負載均衡,SpringCloud的負載均衡算法可以自定義。
集中式LB:
即在服務的消費方和提供方之間使用獨立的LB設施(可以是硬件,如F5, 也可以是軟件,如nginx), 由該設施負責把訪問請求通過某種策略轉發至服務的提供方;
進程內LB:
將LB邏輯集成到消費方,消費方從服務注冊中心獲知有哪些地址可用,然后自己再從這些地址中選擇出一個合適的服務器。
Ribbon就屬于進程內LB,它只是一個類庫,集成于消費方進程,消費方通過它來獲取到服務提供方的地址。
總結
以上是生活随笔為你收集整理的详解Eureka服务注册与发现和Ribbon负载均衡【纯理论实战】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 腾讯万亿级Elasticsearch应用
- 下一篇: 今日的你,上班了吗?