Spring Cloud底層原理(核心元件)

eluanshi12發表於2018-11-26

轉自:拜託!面試請不要再問我Spring Cloud底層原理!

業務場景介紹

開發一個電商網站,要實現支付訂單的功能,流程如下:

  • 建立一個訂單之後,如果使用者立刻支付了這個訂單,我們需要將訂單狀態更新為“已支付”
  • 扣減相應的商品庫存
  • 通知倉儲中心,進行發貨
  • 給使用者的這次購物增加相應的積分

針對上述流程,我們需要有訂單服務、庫存服務、倉儲服務、積分服務。
在這裡插入圖片描述

Spring Cloud核心元件:

Eureka

架構中的 註冊中心,專門負責服務的註冊與發現。
Eureka
Eureka Client:
1.負責將這個服務的資訊註冊到Eureka Server中(告訴Eureka Server,自己在哪臺機器上,監聽著哪個埠)。
2.反過來從Eureka Server中拉取登錄檔,快取到本地(從而知道其他服務在哪裡)
Eureka Server: 註冊中心,裡面有一個登錄檔,儲存了各個服務所在的機器和埠號

Feign

(建立連線,構造請求,傳送請求,解析響應)
基於Feign的 動態代理 機制,根據註解和選擇的機器,拼接請求URL地址,發起請求
Feign

  • 首先,如果你對某個介面定義了@FeignClient註解,Feign就會針對這個介面建立一個動態代理
  • 接著你要是呼叫那個介面,本質就是會呼叫 Feign建立的動態代理,這是核心中的核心
  • Feign的動態代理會根據你在介面上的@RequestMapping等註解,來動態構造出你要請求的服務的地址
  • 最後針對這個地址,發起請求、解析響應

Ribbon

(如果人家庫存服務部署在了5臺機器上,Feign怎麼知道該請求哪臺機器呢?)
服務間發起請求的時候,基於Ribbon做 負載均衡,從一個服務的多臺機器中選擇一臺。
預設使用的最經典的Round Robin 輪詢演算法

Ribbon是和Feign以及Eureka緊密協作,完成工作的:
Ribbon是和Feign以及Eureka緊密協作,完成工作的:

  1. 首先Ribbon會從 Eureka Client裡獲取到對應的服務登錄檔,也就知道了所有的服務都部署在了哪些機器上,在監聽哪些埠號。
  2. 然後Ribbon就可以使用預設的Round Robin演算法,從中選擇一臺機器
  3. Feign就會針對這臺機器,構造併發起請求。

Hystrix

發起請求是通過Hystrix的執行緒池來走的,不同的服務走不同的執行緒池,實現了不同服務呼叫的隔離,避免了服務雪崩的問題。
微服務架構中恐怖的服務雪崩問題
訂單服務在一個業務流程裡需要呼叫三個服務。現在假設訂單服務自己最多隻有100個執行緒可以處理請求,然後呢,積分服務不幸的掛了,每次訂單服務呼叫積分服務的時候,都會卡住幾秒鐘,然後丟擲—個超時異常。

  • 如果系統處於高併發的場景下,大量請求湧過來的時候,訂單服務的100個執行緒都會卡在請求積分服務這塊。導致訂單服務沒有一個執行緒可以處理請求
  • 然後就會導致別人請求訂單服務的時候,發現訂單服務也掛了,不響應任何請求了

但是我們思考一下,就算積分服務掛了,訂單服務也可以不用掛啊!為什麼?

我們結合業務來看:支付訂單的時候,只要把庫存扣減了,然後通知倉庫發貨就OK了

如果積分服務掛了,大不了等他恢復之後,慢慢人肉手工恢復資料!為啥一定要因為一個積分服務掛了,就直接導致訂單服務也掛了呢?不可以接受!

(Hystrix是隔離、熔斷以及降級的一個框架,Hystrix搞很多個小小的執行緒池,每個執行緒池裡的執行緒就僅僅用於請求那個服務。)
在這裡插入圖片描述
但是如果積分服務都掛了,每次呼叫都要去卡住幾秒鐘幹啥呢?有意義嗎?當然沒有!所以我們直接對積分服務熔斷不就得了,比如在5分鐘內請求積分服務直接就返回了,不要去走網路請求卡住幾秒鐘,這個過程,就是所謂的 熔斷

積分服務掛了你就熔斷,好歹你乾點兒什麼啊!別啥都不幹就直接返回啊?沒問題,我們們就來個降級:每次呼叫積分服務,你就在資料庫裡記錄一條訊息,說給某某使用者增加了多少積分,因為積分服務掛了,導致沒增加成功!這樣等積分服務恢復了,你可以根據這些記錄手工加一下積分。這個過程,就是所謂的 降級

Zuul

微服務 閘道器(這個元件是負責網路路由的)
如果前端、移動端要呼叫後端系統,不用去關心後端有幾百個服務,統一從Zuul閘道器進入,閘道器會根據請求中的一些特徵,將請求轉發給對應的服務。
可以做統一的降級、限流、認證授權、安全,等等。

整合:

底層的架構原理

在這裡插入圖片描述

相關文章