1. 程式人生 > >SpringCloud微服務基礎4:Feign

SpringCloud微服務基礎4:Feign

        Spring Cloud Feign是一套基於Netflix Feign實現的宣告式服務呼叫客戶端。它使得編寫Web服務客戶端變得更加簡單。我們只需要通過建立介面並用註解來配置它既可完成對Web服務介面的繫結。它具備可插拔的註解支援,包括Feign註解、JAX-RS註解。它也支援可插拔的編碼器和解碼器。Spring Cloud Feign還擴充套件了對Spring MVC註解的支援,同時還整合了Ribbon和Eureka來提供均衡負載的HTTP客戶端實現。

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

【注意】Feign中已經自動集成了Ribbon負載均衡;同時Feign預設也有對Hystix的整合(預設是關閉Hystix)。

1.工程搭建

1.1、消費者工程引入Feign依賴

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

1.2、Feign的客戶端@FeignClient

在消費者新增一個介面,該介面可以理解為在消費者中的DAO層,內容如下:

@FeignClient("user-service")
public interface UserFeignClient {
    @GetMapping("/user/{id}")
    User queryUserById(@PathVariable("id") Long id);
}

(1)首先這是一個介面,Feign會通過動態代理,幫我們生成實現類。這點跟mybatis的mapper很像;
(2)@FeignClient,宣告這是一個Feign客戶端,類似@Mapper註解。同時通過value屬性指定服務名稱;
(3)介面中的定義方法,完全採用SpringMVC的註解,Feign會根據註解幫我們生成URL,並訪問獲取結果;

修改消費者的service層程式碼如下

@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.3、消費者啟動類開啟Feign@EnableFeignClients

@SpringBootApplication
@EnableDiscoveryClient
@EnableHystrix
@EnableFeignClients // 開啟Feign功能
public class UserConsumerDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserConsumerDemoApplication.class, args);
    }
}

     發現RestTemplate的註冊被我刪除了。Feign中已經自動集成了Ribbon負載均衡,因此我們不需要自己定義RestTemplate了。
 

2.Feign中Hystix支援

   Feign預設也有對Hystix的整合;只不過,預設情況下是關閉的。我們需要修改application.yml的引數來開啟:

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.Feign中請求壓縮及日誌級別

3.1、feign請求壓縮

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

3.2、feign日誌級別

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

1)設定cn.jun包下的日誌級別都為debug ;

logging:
  level:
    cn.jun: debug

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

Feign支援4種級別:
(1)NONE:不記錄任何日誌資訊,這是預設值。
(2)BASIC:僅記錄請求的方法,URL以及響應狀態碼和執行時間
(3)HEADERS:在BASIC的基礎上,額外記錄了請求和響應的頭資訊
(4)FULL:記錄所有請求和響應的明細,包括頭資訊、請求體、元資料。

@Configuration
public class FeignConfig {
    @Bean
    Logger.Level feignLoggerLevel(){
        return Logger.Level.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);
}