視頻指路👉B站黑馬微服務超級推薦!!!
Feign遠程呼叫
為啥需要學Feign呢?我們先來回顧之前寫的代碼
先來看我們以前利用RestTemplate發起遠程呼叫的代碼:

這里就有幾個問題:
- 代碼可讀性差,編程體驗不統一
- 引數復雜URL難以維護
而Feign是一個宣告式的http客戶端,其作用就是幫助我們優雅的實作http請求的發送,解決上面提到的問題
1.Feign替代RestTemplate
1.1 引入依賴
我們在order-service服務的pom檔案中引入feign的依賴:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
1.2 添加注釋
在order-service的啟動類添加注解開啟Feign的功能:
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-O4MBEN7H-1636888023514)(C:\Users\30287\AppData\Roaming\Typora\typora-user-images\image-20211113151318670.png)]](https://img.uj5u.com/2021/11/15/284613151420216.png)
1.3 撰寫Feign的客戶端
在order-service中新建一個介面,內容如下:
@FeignClient("userservice")
public interface UserClient {
@GetMapping("/user/{id}")
User findById(@PathVariable("id") Long id);
}
這個客戶端主要是基于SpringMVC的注解來宣告遠程呼叫的資訊,比如:
- 服務名稱:userservice
- 請求方式:GET
- 請求路徑:/user/{id}
- 請求引數:Long id
- 回傳值型別:User
這樣,Feign就可以幫助我們發送http請求,無需自己使用RestTemplate來發送了
1.4 測驗
修改order-service中的OrderService類中的queryOrderById方法,使用Feign客戶端代替RestTemplate:
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-d0jmODfI-1636888023517)(C:\Users\30287\AppData\Roaming\Typora\typora-user-images\image-20211113151617371.png)]](https://img.uj5u.com/2021/11/15/284613151420217.png)
1.5 總結
使用Feign的步驟:
① 引入依賴
② 添加@EnableFeignClients注解
③ 撰寫FeignClient介面
④ 使用FeignClient中定義的方法代替RestTemplate
2.自定義配置
Feign可以支持很多的自定義配置,如下表所示:
| 型 | 作用 | 說明 |
|---|---|---|
| feign.Logger.Level | 修改日志級別 | 包含四種不同的級別:NONE、BASIC、HEADERS、FULL |
| feign.codec.Decoder | 回應結果的決議器 | http遠程呼叫的結果做決議,例如決議json字串為java物件 |
| feign.codec.Encoder | 請求引數編碼 | 將請求引數編碼,便于通過http請求發送 |
| feign. Contract | 支持的注解格式 | 默認是SpringMVC的注解 |
| feign. Retryer | 失敗重試機制 | 請求失敗的重試機制,默認是沒有,不過會使用Ribbon的重試 |
般情況下,默認值就能滿足我們使用,如果要自定義時,只需要創建自定義的@Bean覆寫默認Bean即可
下面以日志為例來演示如何自定義配置:
2.1 組態檔方式
基于組態檔修改feign的日志級別可以針對單個服務:
feign:
client:
config:
userservice: # 針對某個微服務的配置
loggerLevel: FULL # 日志級別
也可以針對所有服務:
feign:
client:
config:
default: # 這里用default就是全域配置,如果是寫服務名稱,則是針對某個微服務的配置
loggerLevel: FULL # 日志級別
而日志的級別分為四種:
NONE:不記錄任何日志資訊,這是默認值BASIC:僅記錄請求的方法,URL以及回應狀態碼和執行時間HEADERS:在BASIC的基礎上,額外記錄了請求和回應的頭資訊FULL:記錄所有請求和回應的明細,包括頭資訊、請求體、元資料
2.2 Java代碼方式
也可以基于Java代碼來修改日志級別,先宣告一個類,然后宣告一個Logger.Level的物件:
public class DefalutFeignConfiguration {
@Bean
public Logger.Level feignLogLevel(){
return Logger.Level.BASIC; // 日志級別為BASIC
}
}
如果要全域生效,將其放到啟動類的@EnableFeignClients這個注解中:
@EnableFeignClients(defaultConfiguration = DefaultFeignConfiguration .class)
如果是區域生效,則把它放到對應的@FeignClient這個注解中:
@FeignClient(value = "userservice", configuration = DefaultFeignConfiguration .class)
3.Feign使用優化
Feign底層發起http請求,依賴于其它的框架,其底層客戶端實作包括:
URLConnection:默認實作,不支持連接池Apache HttpClient:支持連接池OKHttp:支持連接池
因此提高Feign的性能主要手段就是使用連接池代替默認的URLConnection,
這里我們用Apache的HttpClient來演示:
1)引入依賴
在order-service的pom檔案中引入Apache的HttpClient依賴:
<!--httpClient的依賴 -->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
2)配置連接池
在order-service的application.yml中添加配置:
feign:
client:
config:
default: # default全域的配置
loggerLevel: BASIC # 日志級別,BASIC就是基本的請求和回應資訊
httpclient:
enabled: true # 開啟feign對HttpClient的支持
max-connections: 200 # 最大的連接數
max-connections-per-route: 50 # 每個路徑的最大連接數
總結Feign的優化:
-
日志級別盡量用
basic -
使用
HttpClient或OKHttp代替URLConnection① 引入feign-httpClient依賴
② 組態檔開啟httpClient功能,設定連接池引數
4.最佳實踐
所謂最佳實踐,就是使用程序中總結的經驗,最好的一種使用方式,
自習觀察可以發現,Feign的客戶端與服務提供者的controller代碼非常相似:
feign客戶端:
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-yPpjxVPj-1636888023521)(C:\Users\30287\AppData\Roaming\Typora\typora-user-images\image-20211114185758204.png)]](https://img.uj5u.com/2021/11/15/284613151420218.png)
UserController:
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-qMH31P0o-1636888023524)(C:\Users\30287\AppData\Roaming\Typora\typora-user-images\image-20211114190019659.png)]](https://img.uj5u.com/2021/11/15/284613151420219.png)
有沒有一種辦法簡化這種重復的代碼撰寫呢?
4.1 繼承方式
一樣的代碼可以通過繼承來共享:
- 定義一個API介面,利用定義方法,并基于SpringMVC注解做宣告
- Feign客戶端和Controller都集成改介面

優點:
- 簡單
- 實作了代碼共享
缺點:
-
服務提供方、服務消費方緊耦合
-
引數串列中的注解映射并不會繼承,因此Controller中必須再次宣告方法、引數串列、注解
4.2 抽取方式
Feign的Client抽取為獨立模塊,并且把介面有關的POJO、默認的Feign配置都放到這個模塊中,提供給所有消費者使用,
例如,將UserClient、User、Feign的默認配置都抽取到一個feign-api包中,所有微服務參考該依賴包,即可直接使用

4.3 實作基于抽取的最佳實踐
抽取
首先創建一個module,命名為feign-api:

專案結構:

在 feign-api 中然后引入feign的starter依賴:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
然后,order-service中撰寫的UserClient、User、DefaultFeignConfiguration都復制到feign-api專案中

在order-service中使用 feign-api
首先,洗掉order-service中的UserClient、User、DefaultFeignConfiguration等類或介面
在order-service的pom檔案中中引入feign-api的依賴:
<dependency>
<groupId>com.xn2001.feign</groupId>
<artifactId>feign-api</artifactId>
<version>1.0</version>
</dependency>
修改order-service中的所有與上述三個組件有關的導包部分,改成匯入feign-api中的包
重啟測驗
重啟后,發現服務報錯了:
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-6SqOjUPQ-1636888023532)(C:\Users\30287\AppData\Roaming\Typora\typora-user-images\image-20211114190555513.png)]](https://img.uj5u.com/2021/11/15/2846131514202111.png)
這是因為UserClient現在在cn.itcast.feign.clients包下,
而order-service的@EnableFeignClients注解是在cn.itcast.order包下,不在同一個包,無法掃描到UserClient,
解決掃描包問題
方式一:
指定Feign應該掃描的包:(不推薦)
@EnableFeignClients(basePackages = "cn.itcast.feign.clients")
方式二:
指定需要加載的Client介面:
@EnableFeignClients(clients = {UserClient.class})

最后喜歡的小伙伴,記得三連哦!😏🍭😘
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/357252.html
標籤:java
上一篇:用python實作自動掃雷
