天天看點

SpringCloud服務間内部調用原理

springcloud中各個服務分布在不同的伺服器上,我們常常使用内部服務調用去調用其他服務,那麼他們内部到底是怎麼調用的呢?這裡我們以一個購物app為例子:包含商品服務,倉儲服務,支付服務,購物車服務;

那麼我們這裡從商品服務擷取了商品,加入了購物車,然後準備支付商品款,再通知倉儲進行發貨。那麼這個過程中就設計到服務間調用。

在說明調用原理之前我們先來屢一下思路:每個服務在不同的伺服器上,這些服務直接如何發現彼此?

這就引出了注冊中心(服務注冊與發現);首先每個服務中都會有一個注解@eurekaclient,就是告訴注冊中心關于自己服務的資訊,而且每個服務都有一個注冊中心eurekaserver的位址,(定時)不停地往注冊中心發送心跳告訴自己是否中斷,注冊中心就維護了一張系統資料庫,這張系統資料庫記錄了每個服務的ip,監聽的端口,服務狀态等資訊

那麼如果購物車服務要調用支付服務,那麼它就會問注冊中心:支付服務的注冊資訊是啥?然後購物車拿支付服務注冊資訊之後就緩存到本地服務中。那麼問題又來了,不同伺服器之間調用肯定需要通過網絡請求到對應伺服器上的服務監聽端口?那麼誰來做這個事情呢?

通常我們在沒有使用微服務架構時,都是通過httpclient去調用請求,傳遞參數,然後擷取到相應結果進行處理,但這樣每次都寫重複的代碼是不是很煩人?那微服務springcloud中誰來幹這個活呢?這裡就引出了feign這個元件了。

我們寫過微服務的大家應該都知道,我們在實作控制器時,通常都會以實作一個接口,這個接口在服務間進行調用顯示寫法,那麼這個feign的底層實作原理是啥呢?

我們前面說了要調用不同伺服器之間的服務呀就得使用httpclient形式去調用,feign就是用來幹這個的。

前面我們拿到了支付服務的ip與端口,那麼feign就會将這些資訊拼接起來,形成一個網絡請求:http://服務位址:監聽端口/服務注冊辨別/對應的請求mapping

通常我們都知道加上@feignclient注解的都是一個接口,其實這個feign的原理就是使用的動态代理,通過@feignclient\@requestsmapping\@pathvalue或者@requestbody将請求發送到目标handlemapping上。

這樣我們就解決了不同伺服器之間通信請求連接配接的問題,但是我們微服務通常都會實作分布式部署,同一個服務會部署在不同的多個伺服器上,那麼feign它又怎麼知道我發給那個服務ip上呢?這個工作是誰來做呢?誰來告訴feign呢?那麼這裡又引出了一個元件:ribbon;

沒錯,ribbon就是來告訴feign具體發送到那個ip上的一個負載均衡元件。根據ribbon中的負載均衡政策,每次都會傳回給feign一個ip位址用于服務調用。預設情況下,是均分方式,比如有ip1,ip2,ip3,那麼這個時候來了10個請求,那麼他就先給ip1,再給ip2,再給ip3,這種輪詢政策将請求分布到不用别的伺服器上

那麼如果這個時候其中一台伺服器的服務挂掉了,會怎麼樣呢?内部服務調用還能繼續嗎?内部又會發生什麼操作呢?

首先當然本次内部調用肯定會報服務内部錯誤,因為服務都調不通了嘛。接着出現問題的伺服器無法與注冊中心進行心跳檢查,這個時候注冊中心就會将這個注冊資訊狀态改變将其執行個體下架。然後各用戶端就會更新本地系統資料庫。那麼當再次内部服務調用時就可以調用到可用的伺服器上的服務。

那麼如果當一個一個伺服器上的服務都崩潰了,這個時候支付服務都沒法提供服務了,這個時候又會怎麼樣呢?那這個時候所有調用該服務的線程都會卡在這個服務的調用無法往下走,這個時候嚴重時會導緻調用該服務的服務也奔潰無法服務。

這個地方顯然是不合理的,a服務挂了,關我b服務啥事,最起碼不要讓我也挂了呀。這個時候就會引入一個新東西:hystrix(熔斷器)

我們可以把熔斷器想象為一個保險絲,在電路系統中,一般在所有的家電系統連接配接外部供電的線路中間都會加一個保險絲,當外部電壓過高,達到保險絲的熔點時候,保險絲就會被熔斷,進而可以切斷家電系統與外部電路的聯通,進而保障家電系統不會因為電壓過高而損壞。

hystrix提供的熔斷器就有類似功能,當在一定時間段内服務調用方調用服務提供方的服務的次數達到設定的門檻值,并且出錯的次數也達到設定的出錯門檻值,就會進行服務降級,讓服務調用方之間執行本地設定的降級政策,而不再發起遠端調用。但是hystrix提供的熔斷器具有自我回報,自我恢複的功能,hystrix會根據調用接口的情況,讓熔斷器在closed,open,half-open三種狀态之間自動切換。

open狀态說明打開熔斷,也就是服務調用方執行本地降級政策,不進行遠端調用。

closed狀态說明關閉了熔斷,這時候服務調用方直接發起遠端調用。

half-open狀态,則是一個中間狀态,當熔斷器處于這種狀态時候,直接發起遠端調用。

使用了熔斷器之後,那麼服務之間就不會有強耦合,不會導緻服務間崩潰連鎖反應。進而保證了服務的高可用行,提高了服務的可服務時間。

繼續閱讀