com 组件调用不起来_一文读懂Eureka,Feign,Ribbon,Hystrix,Zuul核心组件间的关系...
Spring Cloud的主要組件
Spring Cloud是目前微服務架構領域的翹楚,無數的書籍博客都在講解這個技術,實際上,Spring Cloud是一個全家桶式的技術棧,包含了很多組件。本文先從其最核心的幾個組件入手,來剖析一下其底層的工作原理。也就是Eureka、Ribbon、Feign、Hystrix、Zuul這幾個組件。
業務場景介紹
先來給大家說一個業務場景,假設咱們現在開發一個電商網站,要實現支付訂單的功能,流程如下:
- 創建一個訂單,如果用戶立刻支付了這個訂單,我們需要將訂單狀態更新為“已支付”
- 扣減相應的商品庫存
- 通知倉儲中心,進行發貨
- 給用戶的這次購物增加相應的積分
針對上述流程,我們需要有訂單服務、庫存服務、倉儲服務、積分服務。整個流程的大體思路如下:
用戶針對一個訂單完成支付之后,就會去找訂單服務,更新訂單狀態
訂單服務調用庫存服務,完成相應功能
訂單服務調用倉儲服務,完成相應功能
訂單服務調用積分服務,完成相應功能
至此,整個支付訂單的業務流程結束
下圖這張圖,清晰表明了各服務間的調用過程:
Spring Cloud組件之間如何運作
Eureka組件
咱們來考慮第一個問題:訂單服務想要調用庫存服務、倉儲服務,或者是積分服務,怎么調用?
- 訂單服務壓根兒就不知道人家庫存服務在哪臺機器上啊!他就算想要發起一個請求,都不知道發送給誰,有心無力!
- 這時候,就輪到Spring Cloud Eureka出場了。Eureka是微服務架構中的注冊中心,專門負責服務的注冊與發現。
通過這個圖來了解Eureka是如何工作的
如上圖所示,庫存服務、倉儲服務、積分服務中都有一個Eureka Client組件,這個組件專門負責將這個服務的信息注冊到Eureka Server中。說白了,就是告訴Eureka Server,自己在哪臺機器上,監聽著哪個端口。而Eureka Server是一個注冊中心,里面有一個注冊表,保存了各服務所在的機器和端口號。
訂單服務里也有一個Eureka Client組件,這個Eureka Client組件會找Eureka Server問一下:庫存服務在哪臺機器啊?監聽著哪個端口啊?倉儲服務呢?積分服務呢?然后就可以把這些相關信息從Eureka Server的注冊表中拉取到自己本地緩存起來。
這時如果訂單服務想要調用庫存服務,不就可以找自己本地的Eureka Client問一下庫存服務在哪臺機器?監聽哪個端口嗎?收到響應后,緊接著就可以發送一個請求過去,調用庫存服務扣減庫存的那個接口!同理,如果訂單服務要調用倉儲服務、積分服務,也是如法炮制。
Feign組件
現在訂單服務確實知道庫存服務、積分服務、倉庫服務在哪里了,同時也監聽著哪些端口號了,但是新問題又來了
- 訂單服務要自己寫一大堆代碼,跟其他服務建立網絡連接,然后構造一個復雜的請求,接著發送請求過去,最后對返回的響應結果再寫一大堆代碼來處理嗎?
- 別急,Feign早已為我們提供好了優雅的解決方案
沒有底層的建立連接、構造請求、解析響應的代碼,直接就是用注解定義一個 FeignClient接口,然后調用那個接口就可以了。人家Feign Client會在底層根據你的注解,跟你指定的服務建立連接、構造請求、發起靕求、獲取響應、解析響應,等等。這一系列臟活累活,人家Feign全給你干了。
Feign實現原理解析
- 首先,如果你對某個接口定義了@FeignClient注解,Feign就會針對這個接口創建一個動態代理
- 接著你要調用哪個接口,本質就是會調用 Feign創建的動態代理,這是核心中的核心
- Feign的動態代理會根據你在接口上的@RequestMapping等注解,來動態構造出你要請求的服務的地址
- 最后針對這個地址,發起請求、解析響應
Ribbon組件
說完了Feign,還沒完。現在新的問題又來了,如果人家庫存服務部署在了3臺機器上,如下所示:
- 192.168.170:9090
- 192.168.171:9090
- 192.168.172:9090
這下糟糕了,人家Feign怎么知道該請求哪臺機器呢?
Ribbon就派上用場了。Ribbon就是專門解決這個問題的。它的作用是負載均衡,會幫你在每次請求時選擇一臺機器,均勻的把請求分發到各個機器上。
Ribbon的負載均衡默認使用的最經典的Round Robin輪詢算法。這是啥?簡單來說,就是如果訂單服務對庫存服務發起10次請求,那就先讓你請求第1臺機器、然后是第2臺機器、第3臺機器、第4臺機器、第5臺機器,接著再來—個循環,第1臺機器、第2臺機器。。。以此類推。
Hystrix組件
當然這些服務正常的情況下,系統是沒有問題的,但是誰也不能保證做的系統就一點問題也沒有,所以萬一要是哪臺機器的服務掛了,怎么辦,服務與服務之間都是緊密聯系的,會不會產生連鎖反應,導致整個系統崩掉。
如上圖,這么多服務互相調用,要是不做任何保護的話,某一個服務掛了,就會引起連鎖反應,導致別的服務也掛。比如積分服務掛了,會導致訂單服務的線程全部卡在請求積分服務這里,沒有一個線程可以工作,瞬間導致訂單服務也掛了,別人請求訂單服務全部會卡住,無法響應。
但是我們思考一下,就算積分服務掛了,訂單服務也可以不用掛啊!為什么?
- 我們結合業務來看:支付訂單的時候,只要把庫存扣減了,然后通知倉庫發貨就OK了
- 如果積分服務掛了,大不了等他恢復之后,慢慢人肉手工恢復數據!為啥一定要因為一個積分服務掛了,就直接導致訂單服務也掛了呢?不可以接受!
- Hystrix閃亮登場了。Hystrix是隔離、熔斷以及降級的一個框架。啥意思呢?說白了,Hystrix會搞很多個小小的線程池,比如訂單服務請求庫存服務是一個線程池,請求倉儲服務是一個線程池,請求積分服務是一個線程池。每個線程池里的線程就僅僅用于請求那個服務。
現在有了Hystrix組件,再次發生積分服務掛了,會怎樣?
- 訂單服務調用庫存服務、倉儲服務的這兩個線程池都是正常工作的,所以這兩個服務不會受到任何影響。
- 訂單服務調用積分服務,如果積分服務掛了,那么這時系統會直接返回一個固定的字符串或者圖片等等,不至于造成卡頓現象,影響客戶體驗。
Zuul組件
業務場景:假設你后臺部署了幾百個服務,現在有個前端兄弟,人家請求是直接從瀏覽器那兒發過來的。人家要請求一下庫存服務,你難道還讓人家記著這服務的名字叫做inventory-service?部署在5臺機器上?就算人家肯記住這一個,你后臺可有幾百個服務的名稱和地址呢?難不成人家請求一個,就得記住一個?
解決辦法:Zuul組件,一種微服務網關組件,負責網絡路由的,類似于路由器的功能。所以一般微服務架構中都必然會設計一個網關在里面,像android、ios、pc前端、微信小程序、H5等等,不用去關心后端有幾百個服務,就知道有一個網關,所有請求都往網關走,網關會根據請求中的一些特征,將請求轉發給后端的各個服務。
總結
最后再來總結一下,上述Spring Cloud核心組件,在微服務架構中,分別扮演的角色:
- Eureka:各個服務啟動時,Eureka Client都會將服務注冊到Eureka Server,并且Eureka Client還可以反過來從Eureka Server拉取注冊表,從而知道其他服務在哪里
- Ribbon:服務間發起請求的時候,基于Ribbon做負載均衡,從一個服務的多臺機器中選擇一臺
- Feign:基于Feign的動態代理機制,根據注解和選擇的機器,拼接請求URL地址,發起請求
- Hystrix:發起請求是通過Hystrix的線程池來走的,不同的服務走不同的線程池,實現了不同服務調用的隔離,避免了服務雪崩的問題
- Zuul:如果前端、移動端要調用后端系統,統一從Zuul網關進入,由Zuul網關轉發請求給對應的服務
文章轉載
https://www.jianshu.com/p/31dfb595170c
總結
以上是生活随笔為你收集整理的com 组件调用不起来_一文读懂Eureka,Feign,Ribbon,Hystrix,Zuul核心组件间的关系...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 流式编程_python 使
- 下一篇: c语言刷新输出_在fx-9860系列上用