概述
毫無疑問,spring cloud是目前微服務架構領域的翹楚,無數的書籍部落格都在講解這個技術。不過大多數講解還停留在對spring cloud功能使用的層面,其底層的很多原理,很多人可能並不知曉。因此本文將通過大量的手繪圖,給大家談談spring cloud微服務架構的底層原理。
實際上,spring cloud是乙個全家桶式的技術棧,包含了很多元件。本文先從其最核心的幾個元件入手,來剖析一下其底層的工作原理。也就是eureka、ribbon、feign、hystrix、zuul這幾個元件。
建立乙個訂單之後,如果使用者立刻支付了這個訂單,我們需要將訂單狀態更新為「已支付」
扣減相應的商品庫存
通知倉儲中心,進行發貨
給使用者的這次購物增加相應的積分
針對上述流程,我們需要有訂單服務、庫存服務、倉儲服務、積分服務。整個流程的大體思路如下:
使用者針對乙個訂單完成支付之後,就會去找訂單服務,更新訂單狀態
訂單服務呼叫庫存服務,完成相應功能
訂單服務呼叫倉儲服務,完成相應功能
訂單服務呼叫積分服務,完成相應功能
至此,整個支付訂單的業務流程結束
下圖這張圖,清晰表明了各服務間的呼叫過程:
二、spring cloud核心元件:eureka
咱們來考慮第乙個問題:訂單服務想要呼叫庫存服務、倉儲服務,或者是積分服務,怎麼呼叫?
訂單服務壓根兒就不知道人家庫存服務在哪台機器上啊!他就算想要發起乙個請求,都不知道傳送給誰,有心無力!
這時候,就輪到spring cloud eureka出場了。eureka是微服務架構中的註冊中心,專門負責服務的註冊與發現。
咱們來看看下面的這張圖,結合圖來仔細剖析一下整個流程:
如上圖所示,庫存服務、倉儲服務、積分服務中都有乙個eureka client元件,這個元件專門負責將這個服務的資訊註冊到eureka server中。說白了,就是告訴eureka server,自己在哪台機器上,監聽著哪個埠。而eureka server是乙個註冊中心,裡面有乙個登錄檔,儲存了各服務所在的機器和埠號
訂單服務裡也有乙個eureka client元件,這個eureka client元件會找eureka server問一下:庫存服務在哪台機器啊?監聽著哪個埠啊?倉儲服務呢?積分服務呢?然後就可以把這些相關資訊從eureka server的登錄檔中拉取到自己本地快取起來。
這時如果訂單服務想要呼叫庫存服務,不就可以找自己本地的eureka client問一下庫存服務在哪台機器?監聽哪個埠嗎?收到響應後,緊接著就可以傳送乙個請求過去,呼叫庫存服務扣減庫存的那個介面!同理,如果訂單服務要呼叫倉儲服務、積分服務,也是如法炮製。
總結一下:
eureka client:負責將這個服務的資訊註冊到eureka server中
eureka server:註冊中心,裡面有乙個登錄檔,儲存了各個服務所在的機器和埠號
三、spring cloud核心元件:feign
現在訂單服務確實知道庫存服務、積分服務、倉庫服務在**了,同時也監聽著哪些埠號了。但是新問題又來了:難道訂單服務要自己寫一大堆**,跟其他服務建立網路連線,然後構造乙個複雜的請求,接著傳送請求過去,最後對返回的響應結果再寫一大堆**來處理嗎?
友情提示,前方高能:
看完上面那一大段**,有沒有感到後背發涼、一身冷汗?實際上你進行服務間呼叫時,如果每次都手寫**,**量比上面那段要多至少幾倍,所以這個事兒壓根兒就不是地球人能幹的。
既然如此,那怎麼辦呢?別急,feign早已為我們提供好了優雅的解決方案。來看看如果用feign的話,你的訂單服務呼叫庫存服務的**會變成啥樣?
看完上面的**什麼感覺?是不是感覺整個世界都乾淨了,又找到了活下去的勇氣!沒有底層的建立連線、構造請求、解析響應的**,直接就是用註解定義乙個 feignclient介面,然後呼叫那個介面就可以了。人家feign client會在底層根據你的註解,跟你指定的服務建立連線、構造請求、發起靕求、獲取響應、解析響應,等等。這一系列髒活累活,人家feign全給你幹了。
首先,如果你對某個介面定義了@feignclient註解,feign就會針對這個介面建立乙個動態**
接著你要是呼叫那個介面,本質就是會呼叫 feign建立的動態**,這是核心中的核心
最後針對這個位址,發起請求、解析響應
四、spring cloud核心元件:ribbon
說完了feign,還沒完。現在新的問題又來了,如果人家庫存服務部署在了5臺機器上,如下所示:
192.168.169:9000
192.168.170:9000
192.168.171:9000
192.168.172:9000
192.168.173:9000
這下麻煩了!人家feign怎麼知道該請求哪台機器呢?
這時spring cloud ribbon就派上用場了。ribbon就是專門解決這個問題的。它的作用是負載均衡,會幫你在每次請求時選擇一台機器,均勻的把請求分發到各個機器上
ribbon的負載均衡預設使用的最經典的round robin輪詢演算法。這是啥?簡單來說,就是如果訂單服務對庫存服務發起10次請求,那就先讓你請求第1臺機器、然後是第2臺機器、第3臺機器、第4臺機器、第5臺機器,接著再來—個迴圈,第1臺機器、第2臺機器。。。以此類推。
此外,ribbon是和feign以及eureka緊密協作,完成工作的,具體如下:
首先ribbon會從 eureka client裡獲取到對應的服務登錄檔,也就知道了所有的服務都部署在了哪些機器上,在監聽哪些埠號。
然後ribbon就可以使用預設的round robin演算法,從中選擇一台機器
feign就會針對這台機器,構造並發起請求。
五、spring cloud核心元件:hystrix
在微服務架構裡,乙個系統會有很多的服務。以本文的業務場景為例:訂單服務在乙個業務流程裡需要呼叫三個服務。現在假設訂單服務自己最多只有100個執行緒可以處理請求,然後呢,積分服務不幸的掛了,每次訂單服務呼叫積分服務的時候,都會卡住幾秒鐘,然後丟擲—個超時異常。
咱們一起來分析一下,這樣會導致什麼問題?
如果系統處於高併發的場景下,大量請求湧過來的時候,訂單服務的100個執行緒都會卡在請求積分服務這塊。導致訂單服務沒有乙個執行緒可以處理請求
然後就會導致別人請求訂單服務的時候,發現訂單服務也掛了,不響應任何請求了
上面這個,就是微服務架構中恐怖的服務雪崩問題,如下圖所示:
如上圖,這麼多服務互相呼叫,要是不做任何保護的話,某乙個服務掛了,就會引起連鎖反應,導致別的服務也掛。比如積分服務掛了,會導致訂單服務的執行緒全部卡在請求積分服務這裡,沒有乙個執行緒可以工作,瞬間導致訂單服務也掛了,別人請求訂單服務全部會卡住,無法響應。
但是我們思考一下,就算積分服務掛了,訂單服務也可以不用掛啊!為什麼?
我們結合業務來看:支付訂單的時候,只要把庫存扣減了,然後通知倉庫發貨就ok了
如果積分服務掛了,大不了等他恢復之後,慢慢人肉手工恢復資料!為啥一定要因為乙個積分服務掛了,就直接導致訂單服務也掛了呢?不可以接受!
現在問題分析完了,如何解決?
這時就輪到hystrix閃亮登場了。hystrix是隔離、熔斷以及降級的乙個框架。啥意思呢?說白了,hystrix會搞很多個小小的執行緒池,比如訂單服務請求庫存服務是乙個執行緒池,請求倉儲服務是乙個執行緒池,請求積分服務是乙個執行緒池。每個執行緒池裡的執行緒就僅僅用於請求那個服務。
打個比方:現在很不幸,積分服務掛了,會咋樣?
當然會導致訂單服務裡的那個用來呼叫積分服務的執行緒都卡死不能工作了啊!但是由於訂單服務呼叫庫存服務、倉儲服務的這兩個執行緒池都是正常工作的,所以這兩個服務不會受到任何影響。
這個時候如果別人請求訂單服務,訂單服務還是可以正常呼叫庫存服務扣減庫存,呼叫倉儲服務通知發貨。只不過呼叫積分服務的時候,每次都會報錯。但是如果積分服務都掛了,每次呼叫都要去卡住幾秒鐘幹啥呢?有意義嗎?當然沒有!所以我們直接對積分服務熔斷不就得了,比如在5分鐘內請求積分服務直接就返回了,不要去走網路請求卡住幾秒鐘,這個過程,就是所謂的熔斷!
那人家又說,兄弟,積分服務掛了你就熔斷,好歹你幹點兒什麼啊!別啥都不幹就直接返回啊?沒問題,咱們就來個降級:每次呼叫積分服務,你就在資料庫裡記錄一條訊息,說給某某使用者增加了多少積分,因為積分服務掛了,導致沒增加成功!這樣等積分服務恢復了,你可以根據這些記錄手工加一下積分。這個過程,就是所謂的降級。
六、spring cloud核心元件:zuul
說完了hystrix,接著給大家說說最後乙個元件:zuul,也就是微服務閘道器。這個元件是負責網路路由的。不懂網路路由?行,那我給你說說,如果沒有zuul的日常工作會怎樣?
假設你後台部署了幾百個服務,現在有個前端兄弟,人家請求是直接從瀏覽器那兒發過來的。打個比方:人家要請求一下庫存服務,你難道還讓人家記著這服務的名字叫做inventory-service?部署在5臺機器上?就算人家肯記住這乙個,你後台可有幾百個服務的名稱和位址呢?難不**家請求乙個,就得記住乙個?你要這樣玩兒,那真是友誼的小船,說翻就翻!
而且有乙個閘道器之後,還有很多好處,比如可以做統一的降級、限流、認證授權、安全,等等。
七、總結:
最後再來總結一下,上述幾個spring cloud核心元件,在微服務架構中,分別扮演的角色:
eureka:各個服務啟動時,eureka client都會將服務註冊到eureka server,並且eureka client還可以反過來從eureka server拉取登錄檔,從而知道其他服務在**
ribbon:服務間發起請求的時候,基於ribbon做負載均衡,從乙個服務的多台機器中選擇一台
hystrix:發起請求是通過hystrix的執行緒池來走的,不同的服務走不同的執行緒池,實現了不同服務呼叫的隔離,避免了服務雪崩的問題
zuul:如果前端、移動端要呼叫後端系統,統一從zuul閘道器進入,由zuul閘道器**請求給對應的服務
以上就是我們通過乙個電商業務場景,闡述了spring cloud微服務架構幾個核心元件的底層原理。
文字總結還不夠直觀?沒問題!我們將spring cloud的5個核心元件通過一張圖串聯起來,再來直觀的感受一下其底層的架構原理:
springcloud 訊息中介軟體使用
一。rabbitmq amqptemplate使用 1.引入依賴 org.springframework.boot spring boot starter amqp 2.訊息傳送方 先注入amqptemplate類 autowired private amqptemplate amqptemplat...
中介軟體 訊息中介軟體學習總結
冪等 在程式設計中.乙個冪等操作的特點是其任意多次執行所產生的影響均與一次執行的影響相同。冪等函式,或冪等方法,是指可以使用相同引數重複執行,並能獲得相同結果的函式。這些函式 不會影響系統狀態,也不用擔心重複執行會對系統造成改變。例如,getusername 和settrue 函式就是乙個冪等函式....
中介軟體作業
主要檔案的 fctrl client linux.c this is sample code generated by rpcgen.these are only templates and you can use them as a guideline for developing your ow...