基本介紹
之前學了LoadBalance,已經能實現負載均衡了,為什麼還需要學習OpoenFeign。簡單的說:LoadBalancer能做的事情,OpenFeign都能做,LoadBalance不能做的事情,OpenFeign也能做。
基本介紹
OpenFeign,主要用於負載均衡,是一個宣告式的Web服務客戶端,從而使WEB服務的呼叫變得很簡單。同時OpenFeign還有一些高階特性,例如超發控制、重試機制、預設HttpClient修改,請求響應壓縮、OpenFeign日誌列印。OpenFeign已經是當前微服務呼叫最常用的技術。
能做什麼
我們在使用LoadBalancer+RestTemplate實現了微服務的負載均衡呼叫,但是在實際開發中,一個介面往往會被多處呼叫,這就需要多次定義重複的程式碼,而OpenFeign簡化了這個過程 。而且也可整合阿里巴巴的Sentinel來提供熔斷、降級功能。透過OpenFeign只需要定義服務繫結介面且以宣告式的方法,就能夠優雅而且簡單的實現服務呼叫。
OpenFeign通用步驟
前面我們已經學習了loadBlancer的引用,https://www.cnblogs.com/luyj00436/p/18580829。OpenFeign使用的原理如下:
接下來使用OpenFeign,為了區別LoadBalancer引用,這裡新建了一個訂單子工程。
引入OpenFeign和LoadBalancer的依賴
訂單子工程引入OpenFeign和LoadBalancer的依賴。
<!-- openFeign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
啟動類上加上@EnableFeignClients
註解
訂單子工程(服務引用端),在啟動類上新增註解``啟動OPenFeignClient功能。
@SpringBootApplication
@EnableDiscoveryClient // 向consul註冊中心時提供服務
@EnableFeignClients(basePackages = "com.atguigu.cloud") //如果FeignClient不在SpringBootApplication的掃描範圍內可以在@EnableFeignClients中指定掃描範圍
public class MainFeign80 {
public static void main(String[] args) {
SpringApplication.run(MainFeign80.class, args);
}
}
在專案通用方法中api包,並儲存api介面
在通用方法中,也引入OpenFeign
的依賴。
<!-- openFeign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
新建支付模組介面
支付模組中,新增@FeignClient
註解,註解的值就是被呼叫的微服務方法。編寫介面中方法,方法上的註解就是別呼叫方法的請求型別和地址。返回值需要和被呼叫介面返回值一致。
@FeignClient(value = "cloud-payment-service")
public interface PayFeignApi {
/**
* 新增訂單
* @return
*/
@PostMapping("/pay/add")
public ResultData<String> addPay();
/**
* 根據Id刪除訂單
* @param id
* @return
*/
@DeleteMapping("/pay/del/{id}")
public ResultData<Integer> deletePay(@PathVariable("id") Integer id);
/**
* 更新訂單資訊
* @param payDTO
* @return
*/
@PutMapping("/pay/update")
public ResultData<String> updatePay(@RequestBody PayDTO payDTO);
/**
* 根據Id獲取訂單資訊
* @param id
* @return
*/
@GetMapping("/pay/get/{id}")
public ResultData<Pay> getById(@RequestParam("id") Integer id);
/**
* 獲取所有的訂單資訊
* @return
*/
@GetMapping("/pay/gets")
public ResultData<List> getPayList();
/**
* 獲取埠號
* @param request
* @return
*/
@GetMapping("/pay/get/port")
public ResultData<String> getPort();
}
呼叫微服務模組(支付模組,cloud-openfeign-order80)調傭feign介面方法
開啟支付模組,新建呼叫方feign方法。
// 注入feign物件
@Resource
private PayFeignApi payFeignApi;
測試後,發現能夠成功呼叫微服務。
OpenFeign的高階特性
前面已經完成了業務模組的基礎使用。接下來,學習一些OpenFeign的高階特性,以應對微服務呼叫時的一些復操作。
OpenFeign超時控制
OpenFeign客戶端的預設等待時間60S,超過這個時間就會報錯
如果業務程式碼比較複雜或者網路原因,有可能出現超時。我們可以設定預設的超時時間。分為兩種設定方式全域性配置和指定設定。指定設定優先順序高於全域性設定。
全域性設定
spring:
cloud:
openfeign:
client:
config:
default:
#指定超時時間最大:3S
read-timeout: 3000
#指定連線時間最大:3S
connect-timeout: 3000
指定設定
spring:
cloud:
openfeign:
client:
config:
#這裡將default換成微服務的名稱
cloud-payment-service:
#指定超時時間最大:3S
read-timeout: 3000
#指定連線時間最大:3S
connect-timeout: 3000
注:可以修改被呼叫的支付模組等待時間,驗證超時控制時間。
try {
TimeUnit.SECONDS.sleep(62); // 設定等待62s
}catch (InterruptedException e){
e.printStackTrace();
}
此時,超時報錯如下:
OpenFeign重試機制
預設情況下,超時連線會返回一個錯。如果我們希望重新嘗試連線呢?
重試機制預設時關閉的,我們只需要編寫一個配置類,配置Retryer物件。
新增OpenFeign的配置類,設定重試機制
@Configuration
public class FeignConfig {
@Bean
public Retryer retryer(){
// Retryer.Default( long period, long maxPeriod, int maxAttempts)
// period : 多長時間後開啟重試機制,這裡設定100ms
// maxPeriod : 重試間隔,這裡設定1s一次
// maxAttempts : 最大請求次數,這裡設定3次
return new Retryer.Default(100,1,3);
}
}
執行測試重試:
前面配置時,設定等待時間3s。3次重試,開始時間和結束時間的時間差為9s。沒有3次重試的過程,需要後續開啟日誌列印才可以看到。
OpenFeign預設HttpClient修改
為什麼要修改HttpClient呢?
OpenFeign中的HttpClient預設採用的是JDK自帶的HttpUrlConection傳送HTTP請求。由於JDK的HttpUrlConection沒有連線池,效能和效率上相對較低。
例如當我們遇到連線超時的錯誤時,也能看到是HttpURLConnection
丟擲的異常~這也能進一步證明預設採用的是HttpURLConnection
。
因此實際開發中,切換成Apache HttpClient 5
是很有必要的。
步驟如下:1. 引入依賴;2. 開啟配置說明
引入依賴
<!-- apche HttpClient的引用-->
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.2.1</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-hc5</artifactId>
<version>13.3</version>
</dependency>
開啟配置(yml檔案為例)
feign:
httpclient:
hc5:
enabled: true # 這是2.x的寫法
# --------------- 以下是SpringBoot 3.0 寫法 ---------------
spring:
cloud:
openfeign:
httpclient:
hc5:
enabled: true
此時,測試超時報錯,已經全部是HttpClient 5
OpenFeign請求/響應壓縮
OpenFeign支援對請求和響應進行GZIP壓縮,以減少通訊過程中的效能損耗。
spring:
cloud:
openfeign:
compression:
request:
#開啟請求壓縮
enabled: true
#達到多大才觸發壓縮
min-request-size: 2048
#觸發壓縮的型別
mime-types: types=text/xml,application/xml,application/json
response:
#開啟響應壓縮
enabled: true
OpenFeign日誌列印功能
OpenFeign需要輸出日誌需要符合兩個條件:
- FeignClient所在的包日誌級別為debug
- Feign的日誌級別在NONE以上
Feign的日誌級別:
NONE:不記錄任何日誌資訊,這是預設值。
BASIC:僅記錄請求的方法,URL以及響應狀態碼和執行時間
HEADERS:在BASIC的基礎上,額外記錄了請求和響應的頭資訊
FULL:記錄所有請求和響應的明細,包括頭資訊、請求體、後設資料。
步驟:定義一個類定義Feign的日誌級別
public class DefaultFeignConfig {
@Bean
public Logger.Level feignLogLevel(){
return Logger.Level.FULL;//日誌級別
}
}
配置檔案中設定feign所在包的列印級別
logging:
level:
#下面是feign介面的包
com:
atguigu:
cloud:
apis:
PayFeignApi: debug
日誌開啟後,可以看到N次請求。
所謂念念不忘,必有迴響。但……如果呼叫的伺服器一直不能給我們回應,一直請求也不是個事兒,否則成了dos攻擊了。這時候需要接受服務降級了。後續學到阿里巴巴的Sentinel,可以結合起來使用。
OpenFeign和Sentinel能夠實現服務降級
之前學了LoadBalance