目錄
一、OpenFeign?是什么,有什么用呢?
二、OpenFeign?客戶端的使用
2.1、遠程調用
1.引入依賴
2.在order-service(發(fā)起遠程調用的微服務)的啟動類添加注解開啟Feign的功能
3.編寫 OpenFeign?客戶端
4.通過 OpenFeign?客戶端發(fā)起遠程調用
2.2、自定義 OpenFeign?配置
1.配置文件方式
2.java代碼方式
2.3、Feign 的性能優(yōu)化
1.引入依賴
2.配置連接池
2.4、Feign 的最佳實踐
1.方式一:給消費者的FeignClient和提供者的controller定義統(tǒng)一的父接口作為標準。
2.方式二(推薦):將FeignClient抽取為獨立模塊,并且把接口有關的POJO(實體類)、默認的Feign配置都放到這個模塊中,提供給所有消費者使用
一、OpenFeign?是什么,有什么用呢?
以往我們是通過 RestTemplate 發(fā)起遠程調用,如下
存在問題如下:
- 代碼可讀性差,編程體驗不統(tǒng)一
- 參數(shù)復雜URL難以維護
Feign? 是一個聲明式的 http 客戶端,其作用就是用來把我們解決上述問題的~
二、OpenFeign?客戶端的使用
2.1、遠程調用
主要分為以下步驟:
1.引入依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
注意:由于SpringCloud Feign高版本(例如 2020.1.0)不使用Ribbon而是使用spring-cloud-loadbalancer,所以需要引用spring-cloud-loadbalancer或者降版本
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
2.在order-service(發(fā)起遠程調用的微服務)的啟動類添加注解開啟Feign的功能
3.編寫 OpenFeign?客戶端
主要是基于SpringMVC的注解來聲明遠程調用的信息,比如:
- 服務名稱:userservice
- 請求方式:GET
- 請求路徑:/user/{id}
- 請求參數(shù):Long id
- 返回值類型:User
import cn.itcast.order.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@Component
@FeignClient("userservice")
public interface UserClients {
@GetMapping("/user/{id}")
User findById(@PathVariable("id") Long id);
}
如果是高版本的 SpringCloud,那么就需要使用 SpringCloud LoadBalencer 做負載均衡(也比較建議).
具體的添加@LoadBalancerClient注解:在調用服務的Service類上添加@LoadBalancerClient注解,并指定服務名。這樣,負載均衡器將根據(jù)配置的屬性來選擇合適的服務實例進行調用。例如:
如下:
@FeignClient(value = "service-name", configuration = LoadBalancerClientConfiguration.class)
public interface MyService {
@LoadBalanced //啟用負載均衡
@GetMapping("/endpoint")
String getEndpointData();
}
4.通過 OpenFeign?客戶端發(fā)起遠程調用
用 Feign 來代替 RestTemplate 是不是十分優(yōu)雅~
2.2、自定義 OpenFeign?配置
2.2.1、超時時間
Ps:OpenFeign早期版本(例如?Hoxton.SR6?)要求服務提供方在1秒內處理業(yè)務邏輯并返回響應。如果超過1秒沒有返回,OpenFeign會直接報錯,不會等待服務執(zhí)行。隨著版本的更新,OpenFeign已經對此做出了調整或優(yōu)化(例如 2021.0.1)。
超時報錯如下:
修改超時時間:
a)在遠程調用方的 application.yml 中配置,指定某個服務提供方的調用超時時間
feign:
client:
config:
product: # 服務名
connect-timeout: 5000 # 配置指定服務連接超時時間
read-timeout: 5000 # 配置指定服務等待超時時間
b)在遠程調用方的 application.yml 中配置,指定所有服務提供方的調用超時時間
feign:
client:
config:
default: # 所有服務
connect-timeout: 5000 # 配置指定服務連接超時時間
read-timeout: 5000 # 配置指定服務等待超時時間
2.2.2、日志使用
OpenFeign 為了更好的方便在開發(fā)過程中檢測 openfeign 數(shù)據(jù)傳遞 和 響應處理,在設計時提供了日志功能.? 默認 openfeign 日志功能需要手動開啟的.
日志級別有以下 4 種:
- NONE:不記錄任何日志.
- BASIC:僅僅記錄請求方法、url、響應狀態(tài)代碼及執(zhí)行時間.
- HEADERS:記錄 Basic 級別的基礎上,記錄請求和響應的header.
- FULL:展示所有 HTTP 協(xié)議狀態(tài).
配置Feign日志有以下兩種方式:
1.配置文件方式(推薦)
a)開啟 openfeign 日志展示
#開啟 openfeign 日志
logging:
level:
org: # 這里是 feign 客戶端接口包路徑
example:
feign: debug
b)全局生效
feign:
client:
config:
default: # 所有服務生效
logger-level: FULL
c)局部生效
feign:
client:
config:
user: # 如果是寫服務名稱,則是針對某個微服務的配置
logger-level: FULL
d)FULL 級別日志展示如下
2.java代碼方式
首先需要聲明一個 Bean,如下
public class FeignClientConfiguration {
@Bean
public Logger.Level feignLogLevel(){
return Logger.Level.BASIC; //一般使用 BASIC 級別,因為太多的日志信息影響效率
}
}
情況一:如果是全局配置,則把它放到@EnableFeignClients這個注解中:
@EnableFeignClients(defaultConfiguration = FeignClientConfiguration.class)
情況二:如果是局部配置,則把它放到@FeignClient這個注解中:
@FeignClient(value = "userservice", configuration = FeignClientConfiguration.class)
2.3、Feign 的性能優(yōu)化
Feign 的底層客戶端實現(xiàn):
- URLConnection:默認實現(xiàn),不支持連接池
- Apache HttpClient :支持連接池
- OKHttp:支持連接池
因此優(yōu)化Feign的性能主要包括:
- 使用連接池代替默認的URLConnection
- 日志級別,最好用basic或none
因此使用 HttpClient 或 OKHttp 代替 URLConnection
1.引入依賴
<!--httpClient的依賴 -->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
2.配置連接池
feign:
client:
config:
default: # default全局的配置
loggerLevel: BASIC # 日志級別,BASIC就是基本的請求和響應信息
httpclient:
enabled: true # 開啟feign對HttpClient的支持
max-connections: 200 # 最大的連接數(shù)
max-connections-per-route: 50 # 每個路徑的最大連接數(shù)
2.4、Feign 的最佳實踐
1.方式一:給消費者的FeignClient和提供者的controller定義統(tǒng)一的父接口作為標準。
仔細觀察我們可以發(fā)現(xiàn), Feign 發(fā)起遠程調用的接口和接收遠程調用請求的 controller 層實現(xiàn)代碼是一樣的,因此,我們我可以把他們的共性提取出來,寫成一個公開的接口,將來我們使用的時候只需要繼承這個接口即可,如下圖
?
?但這種方式存在一定的問題,以下是官方提出的問題:
也就是說
- 服務緊耦合
- 不適用于 Spring MVC (父接口參數(shù)列表中的映射不會被繼承)
2.方式二(推薦):將FeignClient抽取為獨立模塊,并且把接口有關的POJO(實體類)、默認的Feign配置都放到這個模塊中,提供給所有消費者使用
?具體步驟:
1.首先創(chuàng)建一個module,命名為feign-api,然后引入feign的starter依賴
<!--feign 客戶端依賴-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2.將order-service中編寫的UserClient、User、DefaultFeignConfiguration都復制到feign-api項目中
3.在order-service中引入feign-api的依賴
4.修改order-service中的所有與上述三個組件有關的import部分,改成導入feign-api中的包
5.重啟測試
這個時候你重啟項目,項目必然會報以下錯誤
為什么 UserClients 沒有對應的對象呢?
UserClients 之前有對象是因為掃描到?@FeignClient 注解注入了對象?,而現(xiàn)在 order-service 掃描包的范圍是啟動類下的包,但由于我們剛剛把 UserClients 挪到了 feign-api 這個 Module 中,因此,掃描不到該注解,無法注入對象。
總而言之:當定義的FeignClient不在SpringBootApplication的掃描包范圍時,這些FeignClient無法使用。
有以下兩種解決方式:
方式一:指定FeignClient所在包
@EnableFeignClients(basePackages = "cn.itcast.feign.clients")
這種方式會將指定包下的所有東西都拿過來。
方式二(推薦):指定FeignClient字節(jié)碼
@EnableFeignClients(clients = {UserClient.class})
這種方式是精準打擊,只拿指定的類,效率上更推薦使用,用哪個,就指定哪個.文章來源:http://www.zghlxwxcb.cn/news/detail-718565.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-718565.html
到了這里,關于SpringCloud Alibaba - HTTP 客戶端 OpenFeign 、自定義配置、優(yōu)化、最佳實踐的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!