1. 程式人生 > 其它 >SpringCloud之Feign元件的介紹和簡單使用

SpringCloud之Feign元件的介紹和簡單使用

技術標籤:SpringCloud元件Feignspring bootjava

什麼是Feign?

Feign 是一個宣告式的 REST 客戶端,它用了基於介面的註解方式,很方便實現客戶端配置(也就是說讓客戶端的遠端呼叫變得更簡單)。這裡的客戶端指的是服務的消費端。他的底層還是用的RestTemplate+Robbin實現

Feign的作用是什麼?

一句話,簡化RestTemplate的使用,讓遠端呼叫變得更簡單

怎麼使用Feign呢?

使用步驟:

1、在消費端引入 open-feign 依賴

2、在啟動類上使用@EnableFeignClients來開啟Feign支援

3、編寫Feign呼叫介面 ,使用相關的註解進行標註

4、注入Feign的客戶端,然後通過Feign的客戶端發起遠端呼叫

具體實現:

1、在消費端引入 open-feign 依賴

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

2、在啟動類上使用@EnableFeignClients來開啟Feign支援

啟動類:
@EnableDiscoveryClient // 啟用DiscoveryClient  可以隱藏訪問地址,用服務名稱代替
@EnableEurekaClient      //說明這是Eureka的客戶端
@SpringBootApplication   
@EnableFeignClients 		//開啟Feign的功能
public class ConsumerApp {

    public static void main(String[] args) {
        SpringApplication.run(ConsumerApp.class,args);
    }
    
}

3、編寫Feign呼叫介面 ,使用相關的註解進行標註

package com.itheima.consumer.feign;


import com.itheima.consumer.config.FeignLogConfig;
import com.itheima.consumer.domain.Goods;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

/**
 *
 * feign宣告式介面。發起遠端呼叫的。
 *
 String url = "http://FEIGN-PROVIDER/goods/findOne/"+id;
 Goods goods = restTemplate.getForObject(url, Goods.class);
 *
 * 1. 定義介面
 * 2. 介面上添加註解 @FeignClient,設定value屬性為 服務提供者的 應用名稱
 * 3. 編寫呼叫介面,介面的宣告規則 和 提供方介面保持一致。
 * 4. 注入該介面物件,呼叫介面方法完成遠端呼叫
 */
@FeignClient(value = "FEIGN-PROVIDER")
public interface GoodsFeignClient {
    @GetMapping("/goods/findOne/{id}")
    public Goods findGoodsById(@PathVariable("id") int id);
}

4、注入Feign的客戶端,然後通過Feign的客戶端發起遠端呼叫

package com.itheima.consumer.controller;


import com.itheima.consumer.domain.Goods;
import com.itheima.consumer.feign.GoodsFeignClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    private GoodsFeignClient goodsFeignClient;  //注入

    @GetMapping("/goods/{id}")
    public Goods findGoodsById(@PathVariable("id") int id){

        /*
        String url = "http://FEIGN-PROVIDER/goods/findOne/"+id;
        // 3. 呼叫方法
        Goods goods = restTemplate.getForObject(url, Goods.class);

        return goods;*/     //用restTemplate+robbin

        Goods goods = goodsFeignClient.findGoodsById(id);   //用feign呼叫

        return goods;
    }


}

Feign超時配置:

Feign 底層依賴於 Ribbon 實現負載均衡和遠端呼叫。Ribbon預設1秒超時。 如果因為提供服務端因為各種原因如網路延遲,或處理服務比較慢,比如查詢資料庫比較大需要耗時較多等情況造成未在一秒內給消費端返回資料就立馬出問題肯定不合理,所以根據實際的業務情況得更改Feign的超時時間。


# 在客戶端設定Ribbon的超時時間
ribbon:
  ConnectTimeout: 1000 # 連線超時時間 預設1s
  ReadTimeout: 3000 # 邏輯處理的超時時間 預設1s

Feign-日誌記錄配置:

首先要知道的是Feign 只能記錄 debug 級別的日誌資訊。所以要使用feign的日誌記錄就必須先設定日誌級別為debug。如果想清楚的知道,使用Feign來完成遠端呼叫的時候資料傳輸的過程,此時就需要去設定日誌。

使用步驟:

1、在配置檔案中去配置日誌的級別

# 設定當前的日誌級別 debug,feign只支援記錄debug級別的日誌
logging:
  level:
    com.itheima: debug

2、定義一個配置類,配置日誌的記錄方式

package com.itheima.consumer.config;
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FeignLogConfig {
    /*
        NONE,不記錄
        BASIC,記錄基本的請求行,響應狀態碼資料
        HEADERS,記錄基本的請求行,響應狀態碼資料,記錄響應頭資訊
        FULL;記錄完成的請求 響應資料
     */
    @Bean
    public Logger.Level level(){
        return Logger.Level.FULL;
    }
}

3、在@FeignClient這個註解上去通過configuration屬性去使用這個配置類

package com.itheima.consumer.feign;


import com.itheima.consumer.config.FeignLogConfig;
import com.itheima.consumer.domain.Goods;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;


@FeignClient(value = "FEIGN-PROVIDER",configuration = FeignLogConfig.class)
public interface GoodsFeignClient {

    @GetMapping("/goods/findOne/{id}")
    public Goods findGoodsById(@PathVariable("id") int id);

}

通過配置檔案配置:

logging:
  level:
    com.xt.open.jmall.product.remote.feignclients.CartFeignClient: debug

擴充套件:

Feign原理的簡單介紹

  • 啟動時,程式會進行包掃描,掃描所有包下所有@FeignClient註解的類,並將這些類注入到spring的IOC容器中。當定義的Feign中的介面被呼叫時,通過JDK的動態代理來生成RequestTemplate。
  • RequestTemplate中包含請求的所有資訊,如請求引數,請求URL等。
  • RequestTemplate聲場Request,然後將Request交給client處理,這個client預設是JDK的HTTPUrlConnection,也可以是OKhttp、Apache的HTTPClient等。
  • 最後client封裝成LoadBaLanceClient,結合ribbon負載均衡地發起呼叫。