SpringCloud基礎概念學習筆記(Eureka、Ribbon、Feign、Zuul)

語言: CN / TW / HK

SpringCloud基礎概念學習筆記(Eureka、Ribbon、Feign、Zuul)

SpringCloud入門

參考:

SpringCloud是什麼

SpringCloud, 基於SpringBoot提供了一套微服務解決方案,包括服務註冊與發現,配置中心,全鏈路監控,服務閘道器,負載均衡,熔斷器等元件,除了基於NetFlix的開源元件做高度抽象封裝之外,還有一些選型中立的開源元件。

SpringCloud利用SpringBoot的開發便利性,巧妙地簡化了分散式系統基礎設施的開發,SpringCloud為開發人員提供了快速構建分散式系統的一些工具, 包括配置管理,服務發現,斷路器,路由,微代理,事件匯流排,全域性鎖,決策競選,分散式會話等等 ,他們都可以用SpringBoot的開發風格做到一鍵啟動和部署。

SpringBoot並沒有重複造輪子,它只是將目前各家公司開發的比較成熟,經得起實際考研的服務框架組合起來,通過SpringBoot風格進行再封裝,遮蔽掉了複雜的配置和實現原理, 最終給開發者留出了一套簡單易懂,易部署和易維護的分散式系統開發工具包

SpringCloud 是分散式微服務架構下的 一站式解決方案 ,是各個微服務架構落地技術的集合體,俗稱微服務全家桶。

SpringCloud和SpringBoot關係

SpringBoot專注於快速方便的開發單個個體微服務。

SpringCloud是關注全域性的微服務協調整理治理框架,它將SpringBoot開發的一個個單體微服務整合並管理起來,為各個微服務之間提供:配置管理,服務發現,斷路器,路由,微代理,事件匯流排,全域性鎖,決策競選,分散式會話等等整合服務。

SpringBoot可以離開SpringClooud獨立使用,開發專案,但是SpringCloud離不開SpringBoot,屬於依賴關係。

SpringBoot專注於快速、方便的開發單個個體微服務,SpringCloud關注全域性的服務治理框架。

Eureka服務註冊與發現

什麼是Eureka?

Eureka:怎麼讀?(拼音讀法:yi rui ka,伊瑞咔)

Netflix 在設計Eureka 時,遵循的就是AP原則

CAP原則又稱CAP定理,指的是在一個分散式系統中
一致性(Consistency)
可用性(Availability)
分割槽容錯性(Partition tolerance)
CAP 原則指的是,這三個要素最多隻能同時實現兩點,不可能三者兼顧。

Eureka是Netflix的一個子模組,也是核心模組之一。Eureka是一個 基於REST的服務 ,用於定位服務,以實現雲端中間層服務發現和故障轉移,服務註冊與發現對於微服務來說是非常重要的,有了服務發現與註冊,只需要使用服務的識別符號,就可以訪問到服務,而不需要修改服務呼叫的配置檔案了, 功能類似於Dubbo的註冊中心 ,比如Zookeeper。

原理講解

Eureka的基本架構:

SpringCloud 封裝了NetFlix公司開發的Eureka模組來實現 服務註冊和發現

Eureka採用了C-S的架構設計, EurekaServer 作為服務註冊功能的伺服器,他是 服務註冊中心

而系統中的其他微服務。使用Eureka的客戶端連線到EurekaServer並維持心跳連線。這樣系統的維護人員就可以通過EurekaServer來監控系統中各個微服務是否正常執行,SpringCloud的一些其他模組(比如Zuul)就可以通過EurekaServer來發現系統中的其他微服務,並執行相關的邏輯。

Eureka 包含兩個元件: Eureka ServerEureka Client

Eureka Server 提供服務註冊服務,各個節點啟動後,會在EurekaServer中進行註冊,這樣EurekaServer中的服務登錄檔中將會儲存所有可用服務節點的資訊,服務節點的資訊可以在介面中直觀的看到。

Eureka Client是一個Java客戶端,用於簡化EurekaServer的互動,客戶端同時也具備一個內建的,使用輪詢負載演算法的負載均衡器。在應用啟動後,將會向EurekaServer傳送心跳(預設週期為30秒)。如果Eureka Server在多個心跳週期內沒有接收到某個節點的心跳,EurekaServer將會從服務登錄檔中把這個服務節點移除掉(預設週期為90秒)

三大角色

  • Eureka Server:提供服務的註冊於發現。
  • Service Provider:將自身服務註冊到Eureka中,從而使消費方能夠找到。
  • Service Consumer:服務消費方從Eureka中獲取註冊服務列表,從而找到消費服務。

Eureka的自我保護機制

自我保護機制:好死不如賴活著

一句話總結:某時刻某一個微服務不可以用了,eureka不會立刻清理,依舊會對該微服務的資訊進行儲存!

預設情況下,如果EurekaServer在一定時間內沒有接收到某個微服務例項的心跳,EurekaServer將會登出該例項(預設90秒)。但是當網路分割槽故障發生時,微服務與Eureka之間無法正常通行,以上行為可能變得非常危險了--因為微服務本身其實是健康的, 此時本不應該登出這個服務 。Eureka通過 自我保護機制 來解決這個問題--當EurekaServer節點在短時間內丟失過多客戶端時(可能發生了網路分割槽故障),那麼這個節點就會進入自我保護模式。一旦進入該模式,EurekaServer就會保護服務登錄檔中的資訊,不再刪除服務登錄檔中的資料(也就是不會登出任何微服務)。 當網路故障恢復後,該EurekaServer節點會自動退出自我保護模式。

在自我保護模式中,EurekaServer會保護服務登錄檔中的資訊,不再登出任何服務例項。當它收到的心跳數重新恢復到閾值以上時,該EurekaServer節點就會自動退出自我保護模式。它的設計哲學就是寧可保留錯誤的服務註冊資訊,也不盲目登出任何可能健康的服務例項。一句話:好死不如賴活著。

綜上,自我保護模式是一種 應對網路異常的安全保護措施 。它的架構哲學是寧可同時保留所有微服務(健康的微服務和不健康的微服務都會保留),也不盲目登出任何健康的微服務。 使用自我保護模式,可以讓Eureka叢集更加的健壯和穩定。

在SpringCloud中,可以使用 eureka.server.enable-self-preservation = false 禁用自我保護模式 【不推薦關閉自我保護機制】

對比Zookeeper

回顧CAP原則

RDBMS (Mysql、Oracle、sqlServer)--->ACID

NoSQL(redis、mongdb)---> CAP

ACID是什麼?

  • A(Atomicity)原子性
  • C(Consistency) 一致性
  • I (Isolation)隔離性
  • D(Durability)永續性

CAP是什麼?

  • C(Consistency)強一致性
  • A(Availability)可用性
  • P(Partition tolerance)分割槽容錯性

CAP的三進二:CA、AP、CP

CAP理論的核心

  • 一個分散式系統不可能同時很好的滿足一致性,可用性和分割槽容錯性這三個需求
  • 根據CAP原理,將NoSQL資料庫分成了滿足CA原則,滿足CP原則和滿足AP原則三大類:
    • CA:單點叢集,滿足一致性,可用性的系統,通常可擴充套件性較差
    • CP:滿足一致性,分割槽容錯性的系統,通常效能不是特別高
    • AP:滿足可用性,分割槽容錯性的系統,通常可能對一致性要求低一些

作為服務註冊中心,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就認為客戶端與註冊中心出現了網路故障,此時會出現以下幾種情況:

  1. Eureka不再從註冊列表中移除因為長時間沒收到心跳而應該過期的服務
  2. Eureka仍然能夠接受新服務的註冊和查詢請求,但是不會被同步到其他節點上(即保證當前節點依然可用)
  3. 當網路穩定時,當前例項新的註冊資訊會被同步到其他節點中

因此,Eureka可以很好的應對因網路故障導致部分節點失去聯絡的情況,而不會像zookeeper那樣使整個註冊服務癱瘓。

Ribbon負載均衡

Ribbon是什麼?

Ribbon:怎麼讀?(拼音讀法:rui ben,瑞本)

Spring Cloud Ribbon是基於Netflix Ribbon實現的一套 客戶端負載均衡的工具

簡單的說,Ribbon是Netflix釋出的開源專案,主要功能是提供客戶端的軟體負載均衡演算法,將NetFlix的中間層服務連線在一起。Ribbon的客戶端元件提供一系列完整的配置項如:連線超時、重試等等。簡單的說,就是在配置檔案中列出LoadBalancer(簡稱LB:負載均衡)後面所有的機器,Ribbon會自動的幫助你基於某種規則(如簡單輪詢,隨機連線等等)去連線這些機器。我們也很容易使用Ribbon實現自定義的負載均衡演算法!

Ribbon能幹嘛?

LB,即 負載均衡 (Load Balance),在微服務或分散式叢集中經常用的一種應用。

負載均衡簡單的說就是將使用者的請求平攤的分配到多個服務上,從而達到系統的HA(高可用)。

常見的負載均衡軟體有 Nginx,Lvs 等等

Dubbo、SpringCloud中均給我們提供了負載均衡,SpringCloud的負載均衡演算法可以自定義

負載均衡簡單分類:

  • 集中式LB

    • 即在服務的消費方和提供方之間使用獨立的LB設施
    • 如之前學習的Nginx,由該設施負責把訪問請求通過某種策略轉發至服務的提供方!
  • 程序式LB

    • 將LB邏輯整合到消費方,消費方從服務註冊中心獲知有哪些地址可用,然後自己再從這些地址中選出一個合適的伺服器。

    • Ribbon就屬於程序內LB,它只是一個類庫,集成於消費方程序,消費方通過它來獲取到服務提供方的地址!

Ribbon的github地址 : https://github.com/NetFlix/ribbon

Ribbon負載均衡

架構說明:

Ribbon在工作時分成兩步

  • 第一步先選擇EurekaServer,它優先選擇在同一個區域內負載均衡較少的Server。
  • 第二步在根據使用者指定的策略,在從server去到的服務註冊列表中選擇一個地址。

其中Ribbon提供了多種策略,比如 輪詢 (預設),隨機和根據響應時間加權重...等等

總結:

  • Ribbon其實就是一個 軟負載均衡的客戶端元件 ,他可以和其他所需請求的客戶端結合使用,和Eureka結合只是其中的一個例項。

Ribbon核心元件IRule

IRule:根據特定演算法從服務列表中選取一個要訪問的服務!

  • RoundRobinRule【輪詢】
  • RandomRule【隨機】
  • AvailabilityFilterRule【會先過濾掉由於多次訪問故障而處於斷路器跳閘的服務,還有併發的連線數量超過閾值的服務,然後對剩餘的服務列表按照輪詢策略進行訪問】
  • WeightedResponseTimeRule【根據平均響應時間計算所有服務的權重,響應時間越快服務權重越大,被選中的概率越高,剛啟動時如果統計資訊不足,則使用RoundRobinRule策略,等待統計資訊足夠,會切換到WeightedResponseTimeRule】
  • RetryRule【先按照RoundRobinRule的策略獲取服務,如果獲取服務失敗,則在指定時間內會進行重試,獲取可用的服務】
  • BestAvailableRule【會先過濾掉由於多次訪問故障而處於斷路器跳閘狀態的服務,然後選擇一個併發量最小的服務】
  • ZoneAvoidanceRule【預設規則,複合判斷server所在區域的效能和server的可用性選擇伺服器】

Feign負載均衡

Feign是什麼?

Feign:怎麼讀?(拼音讀法:fei en 飛嗯)

feign是 宣告式的web service客戶端 ,它讓微服務之間的呼叫變得更簡單了,類似controller呼叫service。

Spring Cloud集成了Ribbon和Eureka,可在使用Feign時提供負載均衡的http客戶端。

只需要建立一個介面,然後添加註解即可!

feign ,主要是社群,大家都習慣面向介面程式設計。這個是很多開發人員的規範。呼叫微服務訪問的兩種方法:

  1. 微服務名字 【ribbon】
  2. 介面和註解 【feign 】

Feign能幹什麼?

  • Feign旨在使編寫Java Http客戶端變得更容易。

  • 在使用Ribbon + RestTemplate時,利用RestTemplate對Http請求的封裝處理,形成了一套模板化的呼叫方法。但是在實際開發中,由於對服務依賴的呼叫可能不止一處,往往一個介面會被多處呼叫,所以通常都會針對每個微服務自行封裝一些客戶端類來包裝這些依賴服務的呼叫。所以,Feign在此基礎上做了進一步封裝,由他來幫助我們定義和實現依賴服務介面的定義,在Feign的實現下,我們只需要建立一個介面並使用註解的方式來配置它(類似於以前Dao介面上標註Mapper註解,現在是一個微服務介面上面標註一個Feign註解即可。)即可完成對服務提供方的介面繫結,簡化了使用Spring Cloud Ribbon時,自動封裝服務呼叫客戶端的開發量。

Feign集成了Ribbon

利用Ribbon維護了springcloud-Dept的服務列表資訊,並且 通過輪詢實現了客戶端的負載均衡 ,而與Ribbon不同的是,通過Feign只需要定義服務繫結介面且以宣告式的方法,優雅而且簡單的實現了服務呼叫。

小結

Feign通過介面的方法呼叫Rest服務 ( 之前是Ribbon+RestTemplate )。

該請求傳送給Eureka伺服器,通過Feign直接找到服務介面,由於在進行服務呼叫的時候融合了Ribbon技術,所以也支援負載均衡作用!

feign其實不是做負載均衡的,負載均衡是ribbon的功能,feign只是集成了ribbon而已,但是負載均衡的功能還是feign內建的ribbon在做,而不是feign。

feign的作用是替代RestTemplate,效能比較低,但是可以使程式碼可讀性很強。

Hystrix斷路器

什麼是Hystrix?

Hystrix:怎麼讀?(中英結合讀法:hei si tree ke si,黑絲tree克絲)

Hystrix是一個用於 處理分散式系統的延遲和容錯的開源庫 ,在分散式系統裡,許多依賴不可避免的會呼叫失敗,比如超時,異常等,Hystrix能夠保證在一個依賴出問題的情況下,不會導致整體服務失敗,避免級聯故障,以提高分散式系統的彈性。

“斷路器” 本身是一種開關裝置,當某個服務單元發生故障之後,通過斷路器的故障監控(類似熔斷保險絲), 向呼叫方返回一個服務預期的,可處理的備選響應(FallBack),而不是長時間的等待或者丟擲呼叫方法無法處理的異常,這樣就可以保證了服務呼叫方的執行緒不會被長時間不必要的佔用 ,從而避免了故障在分散式系統中的蔓延,乃至雪崩。

Hystrix能幹嘛

  • 服務降級
  • 服務熔斷
  • 服務限流
  • 接近實時的監控
  • .....

官網資料

https://github.com/Netflix/Hystrix/wiki

什麼是服務熔斷?

熔斷機制是對應雪崩效應的 一種微服務鏈路保護機制

當扇出鏈路的某個微服務 不可用或者響應時間太長時 ,會進行服務的降級, 進而熔斷該節點微服務的呼叫,快速返回錯誤的響應資訊 。當檢測到該節點微服務呼叫響應正常後恢復呼叫鏈路。在SpringCloud框架裡熔斷機制通過Hystrix實現。Hystrix會監控微服務間呼叫的狀況,當失敗的呼叫到一定閾值,預設是5秒內20次呼叫失敗就會啟動熔斷機制。

熔斷機制的註解是 @HystrixCommand

什麼是服務降級?

整體資源快不夠了,忍痛將某些服務先關掉,待渡過難關,再開啟回來。

服務降級處理是在客戶端實現完成的,與服務端沒有關係。

小結

  • 服務熔斷 :一般是某個服務故障或者異常引起,類似現實世界中的 “保險絲” , 當某個異常條件被觸發,直接熔斷整個服務,而不是一直等到此服務超時!
  • 服務降級 :所謂降級,一般是從整體負荷考慮,就是當某個服務熔斷之後,伺服器將不再被呼叫,此時客戶端可以自己準備一個本地的fallback回撥,返回一個預設值。這樣做,雖然服務水平下降,但好歹可用,比直接掛掉要強。

服務監控

服務監控hystrixDashboard

除了隔離依賴服務的呼叫以外,Hystrix還提供了準實時的呼叫監控(Hystrix Dashboard),Hystrix會持續地記錄所有通過Hystrix發起的請求的執行資訊,並以統計報表和圖形的形式展示給使用者,包括每秒執行多少請求,多少成功,多少失敗等等。

Netflix通過hystrix-metrics-event-stream專案實現了對以上指標的監控,SpringCloud也提供了Hystrix Dashboard的整合,對監控內容轉化成視覺化介面。

Zuul路由閘道器

什麼是Zuul?

Zuul:怎麼讀?(拼音讀法:ru ou,入嘔)

Zuul包含了對請求的 路由和過濾 兩個最主要的功能:

其中路由功能負責 將外部請求轉發到具體的微服務例項上 ,是實現外部訪問統一入口的基礎,而過濾器功能則負責 對請求的處理過程進行干預 ,是實現請求校驗,服務聚合等功能的基礎。Zuul和Eureka進行整合,將Zuul自身註冊為Eureka服務治理下的應用,同時從Eureka中獲得其他微服務的訊息,也即以後的訪問微服務都是通過Zuul跳轉後獲得。

注意:Zuul服務最終還是會註冊進Eureka

提供:代理 + 路由 + 過濾 三大功能!

Zuul能幹嘛?

  • 路由
  • 過濾

官網文件: https://github.com/Netflix/zuul