宣告式服務呼叫 Spring Cloud Feign
Spring Cloud 為了簡化服務間的呼叫,在Ribbon的基礎上進行了進一步的封裝。單獨抽出了一個元件,就是Spring Cloud Feign。在引入Spring Cloud Feign後,我們只需要建立一個介面並用註解的方式來配置它,即可完成對服務提供方的介面繫結。
Spring Cloud Feign具備可插拔的註解支援,並擴充套件了Spring MVC的註解支援。
下面我們來看一個具體的例子:
服務方具體的介面定義與實現程式碼如下:
呼叫方的使用程式碼如下:
通過上面的程式碼,我們可以看到,呼叫方通過feign程式遠端服務呼叫的時候,非常簡單,就向是在呼叫本地服務一樣。
像之前的建立連線,構造請求,發起請求,獲取響應,解析響應等等操作,對使用者來說都是透明化的,使用者不用關心服務是怎麼實現呼叫的,直接使用即可。
那麼feign是如何實現這套封裝邏輯的呢?
其實
feign底層主要是靠動態代理來實現這整個服務的呼叫過程的。
主要邏輯如下:
- 如果一個介面上定義了@FeignClient註解,Feign就會根據這個介面生成一個動態代理類。
- 如果呼叫方,在呼叫這個定義了@FeignClient註解的介面時,本質上是會呼叫Feign生成的代理類。
- Feign生成的動態代理類,會根據具體介面方法中的@RequestMapping等註解,來動態構造出需要請求的服務地址。
- 最後針對這個地址,再通過Ribbon發起服務呼叫,解析響應等操作。
因為Spring Cloud Feign的使用方式比Spring Cloud Ribbon更方便,所以一般專案中都是使用Feign,而且Feign還有繼承特性,可以將遠端服務介面繼承過來然後再進行自己的個性化擴充套件。因此Feign的使用範圍以及普及率更高一些。
服務容錯保護 Spring Cloud Hystrix
在微服務架構中,我們將系統拆分成多個服務單元,各個服務之間通過服務註冊與訂閱的方式互相依賴。
我們以一個電商網站下單的過程來舉例,在下單的業務操作過程中需要呼叫庫存服務,支付服務,積分、物流等服務。 假設訂單服務最多同一時間只能處理50個請求,這個時候如果積分服務掛了,那麼每次訂單服務去呼叫積分服務的時候,都會卡這麼一段時間,然後才返回超時異常。
在這種場景下會有什麼問題呢?
如果目前電商網站正在搞活動,進行搶購活動,下單的人非常多,這種高併發的場景下,訂單服務的已經同時在處理50個下單請求了,並且都卡在了請求積分服務的過程中。訂單服務已經沒有能力去處理其他請求了。
那麼其他服務再來呼叫訂單服務時,發訂單服務無響應,這樣就導致訂單服務也不可用了。然後其他依賴訂單服務的服務,也最終會導致不可用。 這就是微服務架構中的服務雪崩。
就上圖所示,如果多個服務之間相互呼叫,而不做任何保護措施的話,那麼一個服務掛了,就會產生連鎖反應,導致其他服務也掛了。
其實就算是積分服務掛了,也並不應該導致訂單服務也掛了,積分服務掛了,我們可以跳過積分服務,或者是放一個預設值,然後繼續往下走,等著積分服務恢復了,可以手動恢復一下資料。
那麼Spring Cloud Hystrix就是解決這個問題的元件,他主要是起到熔斷,隔離,降級的作用。
Spring Cloud Hystrix其實是會為每一個服務開闢一個執行緒池,然後每個執行緒池中的執行緒用於對服務的呼叫請求。這樣就算是積分服務掛了,那也只是呼叫積分服務的執行緒池出現問題了,而其他服務的執行緒池還正常工作。 這就是服務的隔離。
這樣訂單服務在的呼叫積分服務的時候,如果發現有問題了,積分服務可以通過 Hystrix返回一個預設值(預設是5秒內20次呼叫失敗就熔斷)。這樣訂單服務就不用在這裡卡住了,可以繼續往下呼叫其他服務進行業務操作了。 這就是服務的熔斷。
雖然說是積分服務掛了,並且也返回了預設值了,但是後續如果積分服務恢復了,想恢復資料怎麼辦呢?這個時候積分服務可以將姐收到的請求記錄下來,或者是打到日誌中,能為後面恢復資料提供依據就行。 這就是服務的降級。
整個過程大致如下圖所示:
API閘道器服務Spring Cloud Zuul
通過上面幾個元件的結合使用,已經能夠完成一個基本的微服務架構了。但是當一個系統中微服務的數量逐漸增多時,一些通用的邏輯,例如:許可權校驗機制,請求過濾,請求路由,限流等等,這些每個服務對外提供能力的時候都要考慮到的邏輯,就會變得冗餘。
這個時候API閘道器的概念應運而生,它類似於物件導向設計模式中的Facade模式(門面模式/外觀模式),所有的外部客戶端訪問都需要經過它來進行排程和過濾。主要實現請求路由、負載均衡、校驗過濾、服務限流等功能。
Spring Cloud Zuul就是Spring Cloud提供的API閘道器元件,它 通過與Eureka進行整合,將自身註冊為Eureka下的應用,從Eureka下獲取所有服務的例項,來進行服務的路由。
Zuul還提供了一套過濾器機制,開發者可以自己指定哪些規則的請求需要執行校驗邏輯,只有通過校驗邏輯的請求才會被路由到具體服務例項上,否則返回錯誤提示。
Spring Cloud Zuul的依賴包
spring-cloud-starter-zuul
本身就包含了對s
pring-cloud-starter-hystrix
和
spring-cloud-starter-ribbon
模組的依賴,所以Zuul天生就擁有執行緒隔離和斷路器的自我保護功能,以及對服務呼叫的客戶端負載功能。
Zuul的路由實現是通過Path和serviceId還實現的,path是一個http請求去除ip和埠號後的方法路徑,例如:
http://192.168.20.12:9001/api-zuul/123
,那麼path就是
/api-zuul/123
,Zuul在配置時支援模糊匹配,若123是動態引數,可以將path配置成
/pai-zuul/**
,serviceId就是服務在Eureka中註冊的服務名稱。
有了統一的閘道器後,再做統一的鑑權、限流、認證授權、安全等方面的工作就會變的更加方便了。
總結
上面總結了Spring Cloud的幾個核心元件,其實Spring Cloud 除了這幾個元件還有一些其他的元件,例如:
-
分散式配置中心:
Spring Cloud Config
; -
訊息匯流排:
Spring Cloud Bus
; -
訊息驅動:
Spring Cloud Stream
; -
分散式服務跟蹤:
Spring Cloud Sleuth
。
主要是後面這些元件我們平時用的不多,而且對於微服務來說有些是有替代品的,所以我暫時就沒有總結。還有一點畢竟我這次總結是為了解決面試的問題,所以後面如果在實際的工作中用到了剩下的這些元件,我會繼續總結的。
好了,總結一下這次的幾個元件的內容吧。
- Spring Cloud Eureka 各個微服務在啟動時將自己註冊到Eureka Server中,並且各個服務中的Eureka Client又能從註冊中心獲取各個服務的例項地址清單。
- Spring Cloud Ribbon 各個服務相互呼叫的時候,通過Ribbon來進行客戶端的負載均衡,從多個例項中根據一定的策略選擇一臺進行請求。
- Spring Cloud Feign 基於動態代理機制,根據註解和引數拼接URL,選擇具體的服務例項發起請求,簡化了服務間相互呼叫的開發工作。
- Spring Cloud Hystrix 呼叫每個服務的時候都是通過執行緒池中的執行緒來發起的,不同的服務走不同的執行緒池,實現了服務的隔離,而且服務不可用時還提供了熔斷機制以及支援降低措施。
- Spring Cloud Zuul 外部請求統一通過Zuul閘道器來進入,支援自定義路由規則,自定義過濾規則,可以實現同一的鑑權、限流、認證等功能。
最後來一個整體的架構圖,將各個元件串起來。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69993516/viewspace-2751007/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Spring Cloud Feign 宣告式服務呼叫SpringCloud
- Spring Cloud Alibaba(8)---Feign服務呼叫SpringCloud
- Spring Cloud實戰系列(三) - 宣告式客戶端呼叫FeignSpringCloud客戶端
- Spring Cloud OpenFeign:基於Ribbon和Hystrix的宣告式服務呼叫SpringCloud
- Spring Cloud Alibaba系列(三)使用feign進行服務呼叫SpringCloud
- spring cloud feign實現遠端呼叫服務傳輸檔案SpringCloud
- spring cloud微服務分散式雲架構-服務消費者FeignSpringCloud微服務分散式架構
- Spring Cloud微服務-基於Eureka的feign呼叫(1)SpringCloud微服務
- spring cloud微服務分散式雲架構(三)-服務消費者(Feign)SpringCloud微服務分散式架構
- Spring Cloud(四)服務提供者 Eureka + 服務消費者 FeignSpringCloud
- Spring Cloud構建微服務架構—服務消費(Feign)SpringCloud微服務架構
- Spring Cloud構建微服務架構—服務消費FeignSpringCloud微服務架構
- Spring Cloud Alibaba 使用Feign進行服務消費SpringCloud
- SpringCloud學習筆記:宣告式呼叫Feign(4)SpringGCCloud筆記
- spring cloud微服務快速教程之(十四)spring cloud feign使用okhttp3--以及feign呼叫引數丟失的說明SpringCloud微服務HTTP
- Spring Cloud Netflix—宣告性REST客戶端:FeignSpringCloudREST客戶端
- 微服務Spring Cloud17_Feign9微服務SpringCloud
- Spring Cloud Alibaba 使用 feign 和 rebion 進行服務消費SpringCloud
- SpringCloud-使用Feign呼叫服務介面SpringGCCloud
- Bug集錦-Spring Cloud Feign呼叫其它介面報錯SpringCloud
- 解決spring cloud Feign遠端呼叫服務,新增headers解決攔截器攔截問題SpringCloudHeader
- Spring Cloud構建微服務架構(Feign)SpringCloud微服務架構
- Spring Cloud Spring Boot mybatis 企業分散式微服務雲(五)服務消費(Feign)【Dalston版】CloudSpring BootMyBatis分散式微服務
- Spring-宣告式事務Spring
- 三 Spring 宣告式事務Spring
- Spring宣告式事務控制Spring
- (22)SpringCloud-使用Feign呼叫服務介面SpringGCCloud
- Spring Cloud 之 Feign.SpringCloud
- Spring Cloud Feign 應用SpringCloud
- spring cloud微服務分散式雲架構(一)-spring cloud 服務註冊與發現SpringCloud微服務分散式架構
- 服務治理: Spring Cloud EurekaSpringCloud
- spring cloud (一)服務治理SpringCloud
- spring-cloud 服務治理SpringCloud
- spring cloud 服務搭建(1)SpringCloud
- Spring宣告式事務@Transactional使用Spring
- spring宣告式事務管理配置Spring
- SpringCloud系列之使用Feign進行服務呼叫SpringGCCloud
- SpringCloud之服務提供與呼叫(Ribbon,Feign)SpringGCCloud