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請求。

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。

3、快速使用

 

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

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

日志輸出效果:

局部配置:

方式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

 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,配置文件修改

application.properties添加配置

#修改某個服務的默認超時時間
# 配置 類別調用商品服務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、自定義攔截器

 

自定義攔截器,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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM