日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring Cloud Feign设计原理

發布時間:2024/9/21 javascript 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring Cloud Feign设计原理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

點擊關注,快速進階高級架構師

作者:亦山札記

什么是Feign?

Feign 的英文表意為“假裝,偽裝,變形”, 是一個http請求調用的輕量級框架,可以以Java接口注解的方式調用Http請求,而不用像Java中通過封裝HTTP請求報文的方式直接調用。Feign通過處理注解,將請求模板化,當實際調用的時候,傳入參數,根據參數再應用到請求上,進而轉化成真正的請求,這種請求相對而言比較直觀。

Feign被廣泛應用在Spring Cloud 的解決方案中,是學習基于Spring Cloud 微服務架構不可或缺的重要組件。

開源項目地址:

https://github.com/OpenFeign/feign

Feign解決了什么問題?

封裝了Http調用流程,更適合面向接口化的變成習慣

在服務調用的場景中,我們經常調用基于Http協議的服務,而我們經常使用到的框架可能有HttpURLConnection、Apache HttpComponnets、OkHttp3 、Netty等等,這些框架在基于自身的專注點提供了自身特性。而從角色劃分上來看,他們的職能是一致的提供Http調用服務。具體流程如下:

Feign是如何設計的?

PHASE 1. 基于面向接口的動態代理方式生成實現類

在使用feign 時,會定義對應的接口類,在接口類上使用Http相關的注解,標識HTTP請求參數信息,如下所示:

在Feign 底層,通過基于面向接口的動態代理方式生成實現類,將請求調用委托到動態代理實現類,基本原理如下所示:



PHASE 2. 根據Contract協議規則,解析接口類的注解信息,解析成內部表現:



Feign 定義了轉換協議,定義如下:

默認Contract 實現

Feign 默認有一套自己的協議規范,規定了一些注解,可以映射成對應的Http請求,如官方的一個例子:

上述的例子中,嘗試調用GitHub.getContributors("foo","myrepo")的的時候,會轉換成如下的HTTP請求:

GET /repos/foo/myrepo/contributors
HOST XXXX.XXX.XXX

Feign 默認的協議規范

具體FeignContract 是如何解析的,不在本文的介紹范圍內,詳情請參考代碼:

https://github.com/OpenFeign/feign/blob/master/core/src/main/java/feign/Contract.java

基于Spring MVC的協議規范SpringMvcContract:

當前Spring Cloud 微服務解決方案中,為了降低學習成本,采用了Spring MVC的部分注解來完成 請求協議解析,也就是說 ,寫客戶端請求接口和像寫服務端代碼一樣:客戶端和服務端可以通過SDK的方式進行約定,客戶端只需要引入服務端發布的SDK API,就可以使用面向接口的編碼方式對接服務:

我們團隊內部就是按照這種思路,結合Spring Boot Starter 的特性,定義了服務端starter,

服務消費者在使用的時候,只需要引入Starter,就可以調用服務。這個比較適合平臺無關性,接口抽象出來的好處就是可以根據服務調用實現方式自有切換:

  • 可以基于簡單的Http服務調用;
  • 可以基于Spring Cloud 微服務架構調用;
  • 可以基于Dubbo SOA服務治理

這種模式比較適合在SaSS混合軟件服務的模式下自有切換,根據客戶的硬件能力選擇合適的方式部署,也可以基于自身的服務集群部署微服務

至于Spring Cloud 是如何實現 協議解析的,可參考代碼:

https://github.com/spring-cloud/spring-cloud-openfeign/blob/master/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/support/SpringMvcContract.java

當然,目前的Spring MVC的注解并不是可以完全使用的,有一些注解并不支持,如@GetMapping,@PutMapping 等,僅支持使用@RequestMapping 等,另外注解繼承性方面也有些問題;具體限制細節,每個版本能會有些出入,可以參考上述的代碼實現,比較簡單。

Spring Cloud 沒有基于Spring MVC 全部注解來做Feign 客戶端注解協議解析,個人認為這個是一個不小的坑。在剛入手Spring Cloud 的時候,就碰到這個問題。后來是深入代碼才解決的.... 這個應該有人寫了增強類來處理,暫且不表,先MARK一下,是一個開源代碼練手的好機會。

PHASE 3. 基于 RequestBean,動態生成Request

根據傳入的Bean對象和注解信息,從中提取出相應的值,來構造Http Request 對象:

PHASE 4. 使用Encoder 將Bean轉換成 Http報文正文(消息解析和轉碼邏輯)

Feign 最終會將請求轉換成Http 消息發送出去,傳入的請求對象最終會解析成消息體,如下所示:

在接口定義上Feign做的比較簡單,抽象出了Encoder 和decoder 接口:

目前Feign 有以下實現:

PHASE 5. 攔截器負責對請求和返回進行裝飾處理

在請求轉換的過程中,Feign 抽象出來了攔截器接口,用于用戶自定義對請求的操作:

比如,如果希望Http消息傳遞過程中被壓縮,可以定義一個請求攔截器:

PHASE 6. 日志記錄

在發送和接收請求的時候,Feign定義了統一的日志門面來輸出日志信息 , 并且將日志的輸出定義了四個等級:

PHASE 7 . 基于重試器發送HTTP請求

Feign 內置了一個重試器,當HTTP請求出現IO異常時,Feign會有一個最大嘗試次數發送請求,以下是Feign核心

代碼邏輯:

重試器有如下幾個控制參數:

具體的代碼實現可參考:

https://github.com/OpenFeign/feign/blob/master/core/src/main/java/feign/Retryer.java

PHASE 8. 發送Http請求

Feign 真正發送HTTP請求是委托給 feign.Client 來做的:

Feign 默認底層通過JDK 的 java.net.HttpURLConnection 實現了feign.Client接口類,在每次發送請求的時候,都會創建新的HttpURLConnection 鏈接,這也就是為什么默認情況下Feign的性能很差的原因??梢酝ㄟ^拓展該接口,使用Apache HttpClient 或者OkHttp3等基于連接池的高性能Http客戶端,我們項目內部使用的就是OkHttp3作為Http 客戶端。

如下是Feign 的默認實現,供參考:

Feign 的性能怎么樣?

Feign 整體框架非常小巧,在處理請求轉換和消息解析的過程中,基本上沒什么時間消耗。真正影響性能的,是處理Http請求的環節。

如上所述,由于默認情況下,Feign采用的是JDK的HttpURLConnection,所以整體性能并不高,剛開始接觸Spring Cloud 的同學,如果沒注意這些細節,可能會對Spring Cloud 有很大的偏見。

我們項目內部使用的是OkHttp3 作為連接客戶端。

https://www.jianshu.com/p/8c7b92b4396c

總結

以上是生活随笔為你收集整理的Spring Cloud Feign设计原理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。