服務調用組件Feign

1.Feign

使用了Ribbon的負載均衡功能,大大簡化了遠程調用時的代碼:

String baseUrl = "http://user-service/user/";
User user = this.restTemplate.getForObject(baseUrl + id, User.class)

你可能以後需要編寫類似的大量重複代碼,格式基本相同,無非參數不一樣。有沒有更優雅的方式,來對這些代碼再次優化呢?

這就是我們接下來要學的Feign的功能了。

1.1.簡介

有道詞典的英文解釋:
在這裏插入圖片描述
爲什麼叫僞裝?

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

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

在這裏插入圖片描述

1.2.快速入門

1.2.1.導入依賴

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

1.2.2.Feign的客戶端

@FeignClient("user-service")
public interface UserFeignClient {

    @GetMapping("/user/{id}")
    User queryUserById(@PathVariable("id") Long id);
}
  • 首先這是一個接口,Feign會通過動態代理,幫我們生成實現類。這點跟mybatis的mapper很像
  • @FeignClient,聲明這是一個Feign客戶端,類似@Mapper註解。同時通過value屬性指定服務名稱
  • 接口中的定義方法,完全採用SpringMVC的註解,Feign會根據註解幫我們生成URL,並訪問獲取結果

改造原來的調用邏輯,不再調用UserDao:

@Service
public class UserService {

    @Autowired
    private UserFeignClient userFeignClient;

    public List<User> queryUserByIds(List<Long> ids) {
        List<User> users = new ArrayList<>();
        ids.forEach(id -> {
            // 我們測試多次查詢,
            users.add(this.userFeignClient.queryUserById(id));
        });
        return users;
    }
}

1.2.3.開啓Feign功能

我們在啓動類上,添加註解,開啓Feign功能

@SpringBootApplication
@EnableDiscoveryClient
@EnableHystrix
@EnableFeignClients // 開啓Feign功能
public class UserConsumerDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserConsumerDemoApplication.class, args);
    }
}
  • 你會發現RestTemplate的註冊被我刪除了。Feign中已經自動集成了Ribbon負載均衡,因此我們不需要自己定義RestTemplate了

1.2.4.啓動測試:

訪問接口:

在這裏插入圖片描述

正常獲取到了結果。

1.3.負載均衡

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

​ [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-6g9qR0OZ-1576480757201)(assets/1525672070679.png)]

因此我們不需要額外引入依賴,也不需要再註冊RestTemplate對象。

另外,我們可以像上節課中講的那樣去配置Ribbon,可以通過ribbon.xx來進行全局配置。也可以通過服務名.ribbon.xx來對指定服務配置:

user-service:
  ribbon:
    ConnectTimeout: 250 # 連接超時時間(ms)
    ReadTimeout: 1000 # 通信超時時間(ms)
    OkToRetryOnAllOperations: true # 是否對所有操作重試
    MaxAutoRetriesNextServer: 1 # 同一服務不同實例的重試次數
    MaxAutoRetries: 1 # 同一實例的重試次數

1.4.Hystix支持

Feign默認也有對Hystix的集成:

在這裏插入圖片描述

只不過,默認情況下是關閉的。我們需要通過下面的參數來開啓:

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

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

1)首先,我們要定義一個類,實現剛纔編寫的UserFeignClient,作爲fallback的處理類

@Component
public class UserFeignClientFallback implements UserFeignClient {
    @Override
    public User queryUserById(Long id) {
        User user = new User();
        user.setId(id);
        user.setName("用戶查詢出現異常!");
        return user;
    }
}

2)然後在UserFeignClient中,指定剛纔編寫的實現類

@FeignClient(value = "user-service", fallback = UserFeignClientFallback.class)
public interface UserFeignClient {

    @GetMapping("/user/{id}")
    User queryUserById(@PathVariable("id") Long id);
}

3)重啓測試:

我們關閉user-service服務,然後在頁面訪問:

在這裏插入圖片描述

1.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 # 設置觸發壓縮的大小下限

注:上面的數據類型、壓縮大小下限均爲默認值。

1.6.日誌級別(瞭解)

前面講過,通過logging.level.xx=debug來設置日誌級別。然而這個對Fegin客戶端而言不會產生效果。因爲@FeignClient註解修改的客戶端在被代理時,都會創建一個新的Fegin.Logger實例。我們需要額外指定這個日誌的級別纔可以。

1)設置com.he包下的日誌級別都爲debug

logging:
  level:
    com.he: debug

2)編寫配置類,定義日誌級別

@Configuration
public class FeignConfig {
    @Bean
    Logger.Level feignLoggerLevel(){
        return Logger.Level.FULL;
    }
}

這裏指定的Level級別是FULL,Feign支持4種級別:

在這裏插入圖片描述

  • NONE:不記錄任何日誌信息,這是默認值。
  • BASIC:僅記錄請求的方法,URL以及響應狀態碼和執行時間
  • HEADERS:在BASIC的基礎上,額外記錄了請求和響應的頭信息
  • FULL:記錄所有請求和響應的明細,包括頭信息、請求體、元數據。

3)在FeignClient中指定配置類:

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

4)重啓項目,即可看到每次訪問的日誌:

在這裏插入圖片描述

發佈了48 篇原創文章 · 獲贊 11 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章