天天看點

SpringCloudAlibaba項目之OpenFeign遠端調用

SpringCloudAlibaba随筆目錄

一、SpringCloudAlibaba項目之父工程搭建

二、SpringCloudAlibaba項目之Nacos搭建及服務注冊

三、SpringCloudAlibaba項目之生産者與消費者

四、SpringCloudAlibaba項目之Ribbon負載均衡

五、SpringCloudAlibaba項目之OpenFeign遠端調用

六、SpringCloudAlibaba項目之Nacos-config配置中心

七、SpringCloudAlibaba項目之Sentinel流量控制

八、SpringCloudAlibaba項目之Seata分布式事務

九、SpringCloudAlibaba項目之GateWay網關

十、SpringCloudAlibaba項目之SkyWalking鍊路追蹤

SpringCloudAlibaba項目之OpenFeign遠端調用

1、OpenFeign  

  OpenFeign是一種聲明式、模闆化的HTTP用戶端。在Spring Cloud中使用OpenFeign,可以做到使用HTTP請求通路遠端服務,就像調用本地方法一樣的,開發者完全感覺不到這是在調用遠端方法,更感覺不到在通路HTTP請求。

SpringCloudAlibaba項目之OpenFeign遠端調用

2、Feign與OpenFeign的差別  

  Feign是Spring Cloud元件中一個輕量級RESTful的HTTP服務用戶端,Feign内置了Ribbon,用來做用戶端負載均衡,去調用服務注冊中心的服務。Feign的使用方式是:使用Feign的注解定義接口,調用接口,就可以調用服務注冊中心的服務。  

  OpenFeign是Spring Cloud在Feign的基礎上支援了SpringMVC的注解,如@RequestMapping等等。OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,并通過動态代理的方式産生實作類,實作類中做負載均衡并調用其他服務。

  說明:springcloud F 及F版本以上 springboot 2.0 以上基本上使用openfeign,openfeign 如果從架構結構上看就是2019年feign停更後出現版本,也可以說大多數新項目都用openfeign ,2018年以前的項目在使用 feign。

SpringCloudAlibaba項目之OpenFeign遠端調用
3、快速使用
SpringCloudAlibaba項目之OpenFeign遠端調用
pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <!-- 繼承父工程版本依賴 -->
    <parent>
        <artifactId>spring-cloud-alibaba</artifactId>
        <groupId>com.qt</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.qt</groupId>
    <artifactId>service-openfeign</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>service-openfeign</name>
    <description>service-openfeign project</description>

    <dependencies>
        <!-- springweb 啟動依賴 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- nacos 服務注冊發現(用戶端)依賴 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!-- openfeign 遠端調用依賴 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!-- springboot 測試類 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.3.7.RELEASE</version>
                <configuration>
                    <mainClass>com.qt.serviceopenfeign.ServiceOpenfeignApplication</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>      

建立Openfeign服務接口

/**
 * 庫存服務接口
 * name:指定調用rest接口所對應的服務名
 * path:指定調用rest接口所在的StockController指定的@RequestMapping
 */
@FeignClient(name = "service-stock",path = "stock")
public interface StockOpenFeignService {

    //聲明需要調用的rest接口對應的方法
    /**
     * 庫存扣減
     * @return
     */
    @RequestMapping("/subStock")
    String subStock();

    /**
     * 庫存新增
     * @return
     */
    @RequestMapping("/addStock")
    String addStock();
}      
OrderController調用:      
/**
 * 訂單服務
 */
@RestController
@RequestMapping("/order")
public class OrderController {

    @Resource
    private StockOpenFeignService stockOpenFeignService;

    /**
     * 新增訂單
     * @return
     */
    @RequestMapping("/addOrder")
    public String addOrder(){
        System.out.println("訂單新增成功");
        //調用庫存扣減
        String result = stockOpenFeignService.subStock();
        return "訂單服務-訂單新增成功:" + result;
    }
}      

application.properties

# 應用名稱
spring.application.name=service-openfeign
# 應用服務 WEB 通路端口
server.port=8060
# Nacos幫助文檔: https://nacos.io/zh-cn/docs/concepts.html
# Nacos認證資訊
spring.cloud.nacos.discovery.username=nacos
spring.cloud.nacos.discovery.password=nacos
# Nacos 服務發現與注冊配置,其中子屬性 server-addr 指定 Nacos 伺服器主機和端口
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
# 注冊到 nacos 的指定 namespace,預設為 public
spring.cloud.nacos.discovery.namespace=public      

通路位址:http://localhost:8060/order/addOrder

SpringCloudAlibaba項目之OpenFeign遠端調用

4、日志配置

  有時候我們遇到bug,接口調用失敗、參數沒收到等問題,或者想看看調用性能,就需要配置OpenFeignde的日志了,以此讓openFeign把請求資訊輸出來。

OpenFeign提供了日志列印功能,我們可以通過配置來調整日恙級别,進而了解Feign 中 Http請求的細節。

日志級别

  • NONE:預設的,不顯示任何日志;
  • BASIC:僅記錄請求方法、URL、響應狀态碼及執行時間;
  • HEADERS:除了BASIC中定義的資訊之外,還有請求和響應的頭資訊;
  • FULL:除了HEADERS中定義的資訊之外,還有請求和響應的正文及中繼資料;

 全局配置:

操作步驟:

  • 在配置類中添加日志配置
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 全局配置:當使用@Configuration 會将配置作用所有的服務提供方
 * 局部配置:如果隻想針對某一個服務進行配置,就不要加@Configuration
 */
@Configuration
public class OpenFeignConfig {

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

注:這裡的logger是feign包裡的

  • application.properties添加配置
# openfeign配置包下(或指定哪些業務接口)以什麼日志級别監聽,springboot的預設日志級别是info,openFeign的日志級别debug就不會輸出,是以需要加上此配置
logging.level.com.qt.serviceopenfeign.openfeign=debug
#logging.level.com.qt.serviceopenfeign.openfeign.StockOpenFeignService=debug      

日志輸出效果:

SpringCloudAlibaba項目之OpenFeign遠端調用

局部配置:

方式1,直接在接口上指定

/**
 * 庫存服務接口
 * name:指定調用rest接口所對應的服務名
 * path:指定調用rest接口所在的StockController指定的@RequestMapping
 */
@FeignClient(name = "service-stock",path = "stock",configuration = OpenFeignConfig.class)
public interface StockOpenFeignService {

    //聲明需要調用的rest接口對應的方法
    /**
     * 庫存扣減
     * @return
     */
    @RequestMapping("/subStock")
    String subStock();

    /**
     * 庫存新增
     * @return
     */
    @RequestMapping("/addStock")
    String addStock(@PathVariable("id") String id);
}      

方式2,application.properties添加配置

# openfeign日志局部配置
feign.client.config.service-stock.loggerLevel=basic      

 5、契約配置

方式1,在OpenFeignConfig中添加配置類

/**
 *全局配置:當使用@Configuration 會将配置作用所有的服務提供方
 * 局部配置:1、如果隻想針對某一個服務進行配置,就不要加@Configuration
 *           2、配置檔案
 */
@Configuration
public class OpenFeignConfig {

    /**
     * 日志配置
     * @return
     */
    /*@Bean
     public Logger.Level feignLoggerLevel(){
         return Logger.Level.FULL;
     }*/

     /**
     * 修改契約配置,支援Feign原生的注解
     * @return
     */
    @Bean
    public Contract feignContract(){
        return new Contract.Default();
    }
}      

方式2,在配置檔案中配置

# openfeign日志局部配置
feign.client.config.service-stock.loggerLevel=basic
#設定為預設的契約 (還原成原生注解)
feign.client.config.service-stock.contract=feign.Contract.Default      

 修改StockOpenFeignService服務接口注解方式

/**
 * 庫存服務接口
 * name:指定調用rest接口所對應的服務名
 * path:指定調用rest接口所在的StockController指定的@RequestMapping
 */
@FeignClient(name = "service-stock",path = "stock",configuration = OpenFeignConfig.class)
public interface StockOpenFeignService {

    //聲明需要調用的rest接口對應的方法
    /**
     * 庫存扣減
     * @return
     */
    //@RequestMapping("/subStock")
    @RequestLine("GET /subStock") //feign的原生注解
    String subStock();

    /**
     * 庫存新增
     * @return
     */
    //@RequestMapping("/addStock")
    @RequestLine("GET /addStock") //feign的原生注解
    //String addStock(@PathVariable("id") String id);
    String addStock(@Param("id") String id); //@PathVariable換成@Param
}      

 通路位址:http://localhost:8060/order/subOrder

SpringCloudAlibaba項目之OpenFeign遠端調用

 6、逾時時間配置

 方式1,在OpenFeignConfig中添加配置類

/**
 * 全局配置:當使用@Configuration 會将配置作用所有的服務提供方
 * 局部配置:1、如果隻想針對某一個服務進行配置,就不要加@Configuration
 *         2、配置檔案
 */
@Configuration
public class OpenFeignConfig {

    /**
     * 日志配置
     * @return
     */
    /*@Bean
     public Logger.Level feignLoggerLevel(){
         return Logger.Level.FULL;
     }*/

     /**
     * 修改契約配置,支援Feign原生的注解
     * @return
     */
    /*@Bean
    public Contract feignContract(){
        return new Contract.Default();
    }*/

    /**
     * 逾時時間配置
     * @return
     */
    @Bean
    public Request.Options options(){
        return new Request.Options(5000,10000);
    }
}      

方式2,配置檔案修改

#修改某個服務的預設逾時時間
# 配置 類别調用商品服務openfeign預設逾時時間  預設連接配接逾時和等待逾時時間都是1s
# 配置指定服務連接配接逾時
#feign.client.config.service-stock.connectTimeout=5000
# 配置指定服務等待逾時
#feign.client.config.service-stock.readTimeout=5000

#修改OpenFeign預設調用所有服務的預設逾時時間
# 配置openfeign預設逾時時間  預設時間 機關毫秒
feign.client.config.default.connectTimeout=5000
feign.client.config.default.readTimeout=5000      

 7、自定義攔截器

SpringCloudAlibaba項目之OpenFeign遠端調用

自定義攔截器,CustomFeignInterceptor

/**
 * 自定義feign攔截器
 */
public class CustomFeignInterceptor implements RequestInterceptor {

    @Override
    public void apply(RequestTemplate requestTemplate) {
        //寫一些自己的業務邏輯 帶上token 什麼之類的
        System.out.println("執行openFeign自定義攔截器");
        String access_token = UUID.randomUUID().toString();
        requestTemplate.header("Authorization",access_token);//設定認證
    }
}      

全局配置

如果寫在配置類中,注入的形式則就是全局的攔截器,因為并沒有指定是為具體服務進行配置。

@Configuration
public class OpenFeignConfig {

   
    /**
     * 自定義feign攔截器
     * @return
     */
    @Bean
    public CustomFeignInterceptor customFeignInterceptor() {
        return new CustomFeignInterceptor();
    }
}      

配置檔案,application.properties

如果寫在配置檔案中指明了服務,則為具體的服務指定一個或者多個攔截器

#在配置檔案中設定feign攔截器
feign.client.config.service-stock.requestInterceptors[0]=com.qt.serviceopenfeign.Interceptor.CustomFeignInterceptor      
SpringCloudAlibaba項目之OpenFeign遠端調用

繼續閱讀