天天看點

SpringCloud FeignFeign

文章目錄

  • Feign
    • 1. 簡介
    • 2. 入門案例
    • 3. 負載均衡Ribbon支援
    • 4. Hystrix支援
    • 5. 請求壓縮
    • 6. 日志級别

Feign

在前面的學習中,我們使用了Ribbon的負載均衡功能,大大簡化了遠端調用時的代碼:

SpringCloud FeignFeign

如果就學到這裡,你可能以後需要編寫類似的大量重複代碼,格式基本相同,無非參數不一樣。有沒有更優雅的方式,來對這些代碼再次優化呢?這就是我們接下來要學的Feign的功能了。

1. 簡介

Feign中文意思是僞裝,為什麼叫僞裝?

Feign可以把Rest的請求進行隐藏,僞裝成類似SpringMVC的Controller一樣。你不用再自己拼接url,拼接參數等等操作,一切都交給Feign去做。

項目首頁:https://github.com/OpenFeign/feign

2. 入門案例

1.導入依賴

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
           

2.Feign的用戶端

在consumer-demo建立一個celient包,用來放Feign用戶端,建立UserClient接口,用來生成調用user-service服務的url。

@FeignClient("user-service")
public interface UserClient {
    @GetMapping("/user/{id}")
    User queryUserById(@PathVariable("id") Long id);
}
           
  • 首先這是一個接口,Feign會通過動态代理,幫我們生成實作類。這點跟Mybatis的mapper很像
  • @FeignClient

    ,聲明這是一個Feign用戶端,同時通過 value 屬性指定服務名稱
  • 接口中的定義方法,完全采用SpringMVC的注解,Feign會根據注解幫我們生成URL,并通路擷取結果

3.編寫新的控制器類

ConsumerFeignController

,使用UserClient通路:

@RestController
@RequestMapping("/cf")
public class ConsumerFeignController {
    
    @Autowired
    private UserClient userClient;
    
    @GetMapping("/{id}")
    public User queryUserById(@PathVariable("id") Long id){
        return userClient.queryUserById(id);
    }
}
           

4.開啟Feign功能

在 ConsumerApplication 啟動類上,添加注解

@EnableFeignClients

,開啟Feign功能

@SpringCloudApplication
@EnableFeignClients  //開啟feign功能
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}
           
Feign中已經自動內建了Ribbon負載均衡,是以不需要自己定義RestTemplate進行負載均衡的配置。

5.啟動測試

通路接口:http://localhost:8080/cf/2

SpringCloud FeignFeign

正常擷取到了結果。

3. 負載均衡Ribbon支援

Feign中本身已經內建了Ribbon依賴和自動配置:

SpringCloud FeignFeign

是以不需要額外引入依賴,也不需要再注冊 RestTemplate 對象。

Fegin内置的Ribbon預設設定了請求逾時時長,預設是1000ms,我們可以通過手動配置來修改這個逾時時長:

ribbon:
	ReadTimeout: 2000 # 讀取逾時時長
	ConnectTimeout: 1000 # 建立連結的逾時時長
           

或者為某一個具體service指定:

user-service:
	ribbon:
		ReadTimeout: 2000 # 讀取逾時時長
		ConnectTimeout: 1000 # 建立連結的逾時時長
           

因為ribbon内部有重試機制,一旦逾時,會自動重新發起請求。如果不希望重試,可以添加配置:

修改 consumer-demo的application.yml添加如下配置 :

ribbon:
	ConnectTimeout: 1000 # 連接配接逾時時長
	ReadTimeout: 2000 # 資料通信逾時時長
	MaxAutoRetries: 0 # 目前伺服器的重試次數
	MaxAutoRetriesNextServer: 0 # 重試多少次服務
	OkToRetryOnAllOperations: false # 是否對所有的請求方式都重試
           

4. Hystrix支援

Feign預設也有對Hystrix的內建:

[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-uNnOhJzY-1615822897527)(https://i.loli.net/2021/03/13/CAuk3wI7FaUXyPQ.png)]

隻不過,預設情況下是關閉的。需要通過下面的步驟來開啟使用:

修改 consumer-demo的application.yml 添加如下配置:

feign:
	hystrix:
		enabled: true # 開啟Feign的熔斷功能
           

但是,Feign中的Fallback配置不像Ribbon中那樣簡單了。

1.首先,要定義一個類,實作剛才編寫的UserClient接口,作為fallback的處理類

@Component
public class UserClientFallback implements UserClient{
    @Override
    public User queryUserById(Long id) {
        User user = new User();
        user.setId(id);
        user.setName("使用者異常");
        return user;
    }
}
           

2.然後在UserClient中,指定剛才編寫的實作類

@FeignClient(value = "user-service",fallback = UserClientFallback.class)
public interface UserClient {
    @GetMapping("/user/{id}")
    User queryUserById(@PathVariable("id") Long id);
}
           

3.重新開機測試

重新開機 consumer-demo 并關閉 user-service 服務,然後在頁面通路:http://localhost:8080/cf/2

SpringCloud FeignFeign

說明發生了服務降級,調用了UserClientFallback中的方法處理了異常。

5. 請求壓縮

Spring Cloud Feign 支援對請求和響應進行GZIP壓縮,以減少通信過程中的性能損耗。通過下面的參數即可開啟請求與響應的壓縮功能:

feign:
	compression:
		request:
			enabled: true # 開啟請求壓縮
		response:
			enabled: true # 開啟響應壓縮
           

同時,我們也可以對請求的資料類型,以及觸發壓縮的大小下限進行設定:

feign:
	compression:
		request:
			enabled: true # 開啟請求壓縮
			mime-types: text/html,application/xml,application/json # 設定壓縮的資料類型
			min-request-size: 2048 # 設定觸發壓縮的大小下限
           

注:上面的資料類型、壓縮大小下限均為預設值。

6. 日志級别

前面講過,通過

logging.level.包名=debug

來設定日志級别。然而這個對Feign用戶端而言不會産生效果。因為

@FeignClient

注解修改的用戶端在被代理時,都會建立一個新的

Fegin.Logger

執行個體。我們需要額外指定這個日志的級别才可以。

1.在 consumer-demo的配置檔案中設定top.peng包下的日志級别都為debug

logging:
  level: 
    top.peng: debug
           

2.編寫配置類,定義Feign日志級别

package top.peng.consumer.config;

import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FeignConfig {
    @Bean
    Logger.Level feignLoggerLevel(){		//Logger為feign包下的,注意正确的導包
        return Logger.Level.FULL;
    }
}
           

這裡指定的Level級别是FULL,Feign支援4種級别:

  • NONE:不記錄任何日志資訊,這是預設值。
  • BASIC:僅記錄請求的方法,URL以及響應狀态碼和執行時間
  • HEADERS:在BASIC的基礎上,額外記錄了請求和響應的頭資訊
  • FULL:記錄所有請求和響應的明細,包括頭資訊、請求體、中繼資料。

3.在 consumer-demo 的 UserClient 接口類上的@FeignClient注解中指定配置類:

@FeignClient(value = "user-service",fallback = UserClientFallback.class,configuration = FeignConfig.class)
public interface UserClient {
    @GetMapping("/user/{id}")
    User queryUserById(@PathVariable("id") Long id);
}
           

4.重新開機項目,即可看到每次通路的日志:

SpringCloud FeignFeign

⏮ 上一 節: Hystrix ⏭下一節:SpringCloud Gateway網關