OpenFeign服务接口调用

1. 提问

  1. 已经有loadbalancer为什么还要学习OpenFeign?

  1. 两个都有道理的话,我日常用那个?

2. 是什么

2.1. 官网

Spring Cloud OpenFeign

2.2. github

GitHub - spring-cloud/spring-cloud-openfeign: Support for using OpenFeign in Spring Cloud apps

2.3. 简介

Feign 是一个声明式的 Web Service 客户端。它使编写 Web Service 客户端更容易。要使用 Feign,需要创建一个接口并对其进行注解。它有可插拔的注解支持,包括 Feign 注解和 JAX-RS 注解。Feign 还支持可插拔的编码器和解码器。Spring Cloud 增加了对 Spring MVC 注解的支持,并支持使用 Spring Web 中默认使用的 HttpMessageConverters。Spring Cloud 集成了 Eureka、Spring Cloud CircuitBreaker以及Spring Cloud LoadBalancer,以便在使用Feign时提供一个负载均衡的http客户端。

Spring Cloud OpenFeign是一种基于Spring Cloud的声明式REST客户端,它简化了与HTTP服务交互的过程。它将REST客户端的定义转化为Java接口,并且可以通过注解的方式来声明请求参数、请求方式、请求头等信息,从而使得客户端的使用更加方便和简洁。同时,它还提供了负载均衡和服务发现等功能,可以与Eureka、Consul等注册中心集成使用。Spring Cloud OpenFeign能够提高应用程序的可靠性、可扩展性和可维护性,是构建微服务架构的重要工具之一。

OpenFeign是Spring Cloud项目中的⼀个模块,它是基于Feign开发的,可以看作是对Feign的进⼀步封装和增强。Feign是⼀个声明式、模板化的HTTP客户端,它的目标是简化HTTP API开发。

OpenFeign在Feign的基础上增加了对Spring MVC注解、Spring Boot自动配置等特性的⽀持,并且集成了SpringCloud的服务发现和负载均衡功能。相比于Feign,OpenFeign更适合在Spring Cloud微服务架构中使用。

3. 能干嘛

  1. 可插拔的注解支持,包括Feign注解和JAX-RS注解
  2. 支持可插拔的HTTP编码器和解码器
  3. 支持Sentinel和它的Fallback
  4. 支持SpringCloudLoadBalancer的负载均衡
  5. 支持HTTP请求和响应的压缩

  1. 前面在使用SpringCloud LoadBalancer+RestTemplate时,利用RestTemplate对http请求的封装处理形成了一套模版化的调用方法。
  2. 但是在实际开发中,由于对服务依赖的调用可能不止一处,往往一个接口会被多处调用,所以通常都会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用。所以,OpenFeign在此基础上做了进一步封装,由他来帮助我们定义和实现依赖服务接口的定义。在OpenFeign的实现下,我们只需创建一个接口并使用注解的方式来配置它(在一个微服务接口上面标注一个@FeignClient注解即可),即可完成对服务提供方的接口绑定,统一对外暴露可以被调用的接口方法,大大简化和降低了调用客户端的开发量,也即由服务提供者给出调用接口清单,消费者直接通过OpenFeign调用即可,O(∩_∩)O。
  3. OpenFeign同时还集成SpringCloud LoadBalancer。
    1. 可以在使用OpenFeign时提供Http客户端的负载均衡,也可以集成阿里巴巴Sentinel来提供熔断、降级等功能。而与SpringCloud LoadBalancer不同的是,通过OpenFeign只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用。

4. 相比于RestTemplate,OpenFeign的优势在于

在Spring Cloud中,OpenFeign是⼀个声明式的HTTP客户端,它的作用是用于与RESTful API进行通信。相比于RestTemplate,OpenFeign的优势在于:

  1. 更加简洁的代码:使用OpenFeign,只需要定义⼀个接口,而不需要写任何实现代码。在接口上使用注解即可描述API的细节,OpenFeign会自动生成实现类并处理所有的HTTP细节。
  1. 更好的可读性和可维护性:OpenFeign使用注解来描述API,这使得代码更加易于阅读和理解。此外,OpenFeign的接口和实现分离,使得代码更加易于维护。
  1. 内置的负载均衡:OpenFeign内置了负载均衡功能,可以与Spring Cloud的服务发现组件(如Nacos)集成,从而自动地选择合适的服务实例进行请求。这使得在分布式系统中进行服务调用更加容易。
  1. 更加灵活的扩展性:OpenFeign是高度可配置的,可以通过自定义的编码器和解码器来处理不同的请求和响应格式。同时,OpenFeign还⽀持自定义的拦截器来实现更加复杂的请求和响应处理逻辑。

5. OpenFeign通用步骤(怎么玩)

5.1. 接口 + 注解

  1. 微服务Api接口 + @FeignClient注解标签

  1. 架构说明图
    1. 服务消费者80 → 调用含有@FeignClient注解的Api服务接口 → 服务提供者(8001/8002/8003)

5.2. 流程步骤

5.2.1. 建Module:cloud-consumer-feign-order80

5.2.2. 该pom

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.yq.springcloud</groupId>
        <artifactId>SpringCloud2024</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>cloud-consumer-feign-order80</artifactId>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <!-- 引入自己定义的api通用包 -->
        <dependency>
            <groupId>com.yq.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
        <!--web + actuator-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <!--SpringCloud consul discovery-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-discovery</artifactId>
        </dependency>

        <!--openfeign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!--hutool-all-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
        </dependency>
        <!--fastjson2-->
        <dependency>
            <groupId>com.alibaba.fastjson2</groupId>
            <artifactId>fastjson2</artifactId>
        </dependency>
        <!-- swagger3 调用方式 http://你的主机IP地址:5555/swagger-ui/index.html -->
        <dependency>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

5.2.3. 写yml

server:
  port: 80

spring:
  application:
    name: cloud-consumer-openfeign-order
  ####Spring Cloud Consul for Service Discovery
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        prefer-ip-address: true #优先使用服务ip进行注册
        service-name: ${spring.application.name}

5.2.4. 主启动(修改类名为MainOpenFeign80)

  • 主启动类上面配置@EnableFeignClients表示开启OpenFeign功能并激活
package com.yq.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableDiscoveryClient //该注解用于向使用consul为注册中心时注册服务
@EnableFeignClients(basePackages = "com.yq.springcloud.apis")//启用feign客户端,定义服务+绑定接口,以声明式的方法优雅而简单的实现服务调用
public class MainOpenFeign80 {
    public static void main(String[] args) {
        SpringApplication.run(MainOpenFeign80.class, args);
    }
}

5.2.5. 业务类

5.2.5.1. 按照架构说明图进行编码准备

订单模块要去调用支付模块,订单和支付两个微服务,需要通过Api接口解耦,一般不要在订单模块写非订单相关的业务,自己的业务自己做+其它模块走FeignApi接口调用。

5.2.5.2. 修改cloud-api-commons通用模块
5.2.5.2.1. 引入openfeign依赖
        <!--openfeign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

5.2.5.2.2. 新建服务接口PayFeignApi,头上配置@FeignClient注解
package com.yq.springcloud.apis;

import org.springframework.cloud.openfeign.FeignClient;

@FeignClient("cloud-payment-service")
public interface PayFeignApi {
}

5.2.5.2.3. 参考微服务8001的Controller层,新建PayFeignApi接口
  • 小bug注意一下,@PathVariable("id") 注解必须规范!!!

  • @RequestMapping和@FeginClient注解不能同时使用:
    • 使用@FeignClient自己的path属性指定路径前缀

package com.yq.springcloud.apis;

import com.yq.springcloud.entity.PayDTO;
import com.yq.springcloud.resp.ResultData;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;

@FeignClient(value = "cloud-payment-service", path = "pay")
public interface PayFeignApi {

    @PostMapping("add")
    ResultData add(@RequestBody PayDTO payDTO);


    @DeleteMapping("delete/{id}")
    ResultData delete(@PathVariable("id") Integer id);

    @PutMapping("update")
    ResultData update(@RequestBody PayDTO payDTO);

    @GetMapping("getById/{id}")
    public ResultData getById(@PathVariable("id") Integer id);

    @GetMapping("getAll")
    public ResultData getAll();
}

5.2.5.2.4. 新建OrderController
package com.yq.springcloud.controller;

import com.yq.springcloud.apis.PayFeignApi;
import com.yq.springcloud.entity.PayDTO;
import com.yq.springcloud.resp.ResultData;
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 PayFeignApi payFeignApi;

    @GetMapping("/addOrder")
    public ResultData addOrder(PayDTO payDTO){
        return payFeignApi.add(payDTO);
    }

    @GetMapping("/getPayInfo/{id}")
    public ResultData getPayInfo(@PathVariable("id") Integer id){
        return payFeignApi.getById(id);
    }
}

5.2.6. 测试

  1. 先启动 consul
  2. 再启动微服务8001
  3. 再启动动cloud-consumer-feign-order80
  4. postman测试:
    1. 新增:http://localhost/order/addOrder?payNo=2&orderNo=2&userId=2&amount=100

    1. 获取:http://localhost/order/getPayInfo/8

5.2.7. 测试负载均衡

5.2.7.1. cloud-api-commons 模块下新增 Consul
  1. 注意:一定要指定contextId,因为如果没有指定上下文Id的话,默认是服务名,由于之前的OrderFeignApi已经使用了,所以这儿特别指定上下文id,否则会出现以下错误。

官方解释:

package com.yq.springcloud.apis;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

@FeignClient(value = "cloud-payment-service", contextId = "cloud-payment-service-consul", path = "consul")
public interface ConsulFeignApi {

    @GetMapping("getInfoByConsul")
    String getInfoByConsul();
}

5.2.7.2. cloud-consumer-feign-order80新增ConsulController
package com.yq.springcloud.controller;

import com.yq.springcloud.apis.ConsulFeignApi;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("consul")
public class ConsulController {
    @Autowired
    private ConsulFeignApi consulFeignApi;

    @GetMapping("getInfoByConsul")
    public String getInfoByConsul(){
        return consulFeignApi.getInfoByConsul();
    }
}

5.2.7.3. 测试
  1. 先启动 consul
  2. 再启动微服务8001、8002、8003
  3. 再启动动cloud-consumer-feign-order80
  4. postmam测试:
    1. http://localhost/consul/getInfoByConsul,出现轮询效果。

6. OpenFeign高级特性

6.1. @EnableFeignClients属性解析

  • @EnableFeignClients用户开启Feign自动配置。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(FeignClientsRegistrar.class)
public @interface EnableFeignClients {
 
    // basePackages的别名,允许更简洁的注释声明,例如:@ComponentScan("org.my.pkg")而不是@ComponentScan(basePackages="org.my.pkg")
    String[] value() default {};
 
    // 用户扫描Feign客户端的包,也就是@FeignClient标注的类,与value同义,并且互斥
    String[] basePackages() default {};
 
    // basePackages()的类型安全替代方案,用于指定要扫描带注释的组件的包。每个指定类别的包将被扫描。 考虑在每个包中创建一个特殊的无操作标记类或接口,除了被该属性引用之外没有其他用途。
    Class<?>[] basePackageClasses() default {};
 
    // 为所有假客户端定制@Configuration,默认配置都在FeignClientsConfiguration中,可以自己定制
    Class<?>[] defaultConfiguration() default {};
 
    // 可以指定@FeignClient标注的类,如果不为空,就会禁用类路径扫描
    Class<?>[] clients() default {};
 
}

6.2. @FeignClient属性解析

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface FeignClient {
 
    // 服务的名称,可以包含可选的协议前缀。在所有的客户端中,必须指定一个名称,无论是否提供了 URL。
    @AliasFor("name")
    String value() default "";
 
    // 该类的Bean名称
    String contextId() default "";
 
    // name和value属性用于标注客户端名称,也可以用${propertyKey}获取配置属性
    @AliasFor("value")
    String name() default "";
 
    // 弃用 被qualifiers()替代。
    @Deprecated
    String qualifier() default "";
 
    // 模拟客户端的@Qualifiers值。如果qualifier()和qualifiers()都存在,我们将使用后者,除非qualifier()返回的数组为空或只包含空值或空白值,在这种情况下,我们将首先退回到qualifier(),如果也不存在,则使用default = contextId + "FeignClient"。
    String[] qualifiers() default {};
 
    // 绝对URL或可解析主机名
    String url() default "";
 
    // 是否应该解码404而不是抛出FeignExceptions
    boolean decode404() default false;
 
    // 用于模拟客户端的自定义配置类。可以包含组成客户端部分的覆盖@Bean定义,默认配置都在FeignClientsConfiguration类中,可以指定FeignClientsConfiguration类中所有的配置
    Class<?>[] configuration() default {};
 
    // 指定 Feign 客户端接口的回退类。回退类必须实现被该注解标记的接口,并且必须是有效的 Spring bean。
    Class<?> fallback() default void.class;
 
    // 为指定的假客户端接口定义一个fallback工厂。fallback工厂必须生成fallback类的实例,这些实例实现了由FeignClient注释的接口。
    Class<?> fallbackFactory() default void.class;
 
    // 所有方法级映射使用的路径前缀
    String path() default "";
 
    // 是否将 Feign 代理标记为主要(primary)bean。默认为 true。
    boolean primary() default true;
}

可以通过以下任何一种方式向Feign客户端提供URL:

6.3. OpenFeign超时控制

在Spring Cloud微服务架构中,大部分公司都是利用OpenFeign进行服务间的调用,而比较简单的业务使用默认配置是不会有多大问题的,但是如果是业务比较复杂,服务要进行比较繁杂的业务计算,那后台很有可能会出现Read Timeout这个异常,因此定制化配置超时时间就有必要了。

6.3.1. 超时设置,故意设置超时演示出错情况自己使坏写bug

  1. 服务提供方cloud-provider-payment8001故意写暂停62秒钟程序
    1. 为什么写62秒?为什么写62秒?为什么写62秒?
    @GetMapping("getById/{id}")
    public ResultData<Pay> getById(@PathVariable("id") Integer id){

        // 服务提供方业务处理,为了测试 feign 的超时时间控制
        try {
            TimeUnit.SECONDS.sleep(62);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        Pay pay = payService.getById(id);
        return ResultData.success(pay);
    }

  1. 服务调用方cloud-consumer-feign-order80写好捕捉超时异常
    @GetMapping("/getPayInfo/{id}")
    public ResultData getPayInfo(@PathVariable("id") Integer id){

        ResultData data = null;
        try {
            System.out.println("调用开始 ===============》 " + DateUtil.now());
            data = payFeignApi.getById(id);
        } catch (Exception e) {
            System.out.println("调用结束 ===============》 " + DateUtil.now());
            throw new RuntimeException(e);
        }
        return data;
    }

  1. 测试:
    1. http://localhost/order/getPayInfo/1
    2. 错误结果:

  1. 结论:
    1. OpenFeign默认等待60秒钟,超过后报错

6.3.2. 官网解释+配置处理

6.3.2.1. 两个关键参数

6.3.2.2. 超时配置参考官网要求

6.3.3. 修改cloud-consumer-feign-order80 YML文件里需要开启OpenFeign客户端超时控制

6.3.3.1. 全局配置
  1. 修改yml配置文件
server:
  port: 80

spring:
  application:
    name: cloud-consumer-openfeign-order
  ####Spring Cloud Consul for Service Discovery
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        prefer-ip-address: true #优先使用服务ip进行注册
        service-name: ${spring.application.name}
    openfeign:
      client:
        config:
          default:
            #连接超时时间
            connect-timeout: 5000
            #读取超时时间
            read-timeout: 5000

  1. 5秒测试

6.3.3.2. 指定配置
  1. 修改yml配置文件
    1. 如果指定了服务,则优先使用单个服务的配置,没有就是默认的
    2. 注意:这个服务名称值的是 @FeignClient 的 contextId 属性,而不是 value属性。

server:
  port: 80

spring:
  application:
    name: cloud-consumer-openfeign-order
  ####Spring Cloud Consul for Service Discovery
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        prefer-ip-address: true #优先使用服务ip进行注册
        service-name: ${spring.application.name}
    openfeign:
      client:
        config:
          default:
            #连接超时时间
            connect-timeout: 5000
            #读取超时时间
            read-timeout: 5000
          # 为cloud-payment-service这个服务单独配置超时时间,单个配置的超时时间将会覆盖全局配置
          cloud-payment-service:
            #连接超时时间
            connectTimeout: 3000
            #读取超时时间
            readTimeout: 3000

  1. 3秒测试

6.4. OpenFeign重试机制

6.4.1. 默认重试是关闭的,给了默认值

6.4.2. 默认关闭重试机制,测试看看

  • 只会调用一次后就结束,添加重试机制。

6.4.3. 开启Retryer功能

  1. 新增配置类FeignConfig并修改Retryer配置
package com.yq.springcloud.config;

import feign.Retryer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import static java.util.concurrent.TimeUnit.SECONDS;

@Configuration
public class FeignConfig {

    @Bean
    public Retryer myRetryer() {
        //return Retryer.NEVER_RETRY; //Feign默认配置是不走重试策略的

        //最大请求次数为3(1+2),初始间隔时间为100ms,重试间最大间隔时间为1s
        return new Retryer.Default(100, SECONDS.toMillis(1), 3);
    }
}

  1. 结果:总体调用3次,3 =1(default)+2。

  1. 补充一句:
  • 如果觉得效果不明显的同学,后续演示feign 日志功能的时候再演示,目前控制台没有看到3次重试过程,只看到结果,正常的,正确的,是feign的日志打印问题。

6.5. OpenFeign默认HttpClient修改

6.5.1. 官网说明

6.5.2. 是什么

  • OpenFeign中http client 如果不做特殊配置,OpenFeign默认使用JDK自带的 HttpURLConnection 发送HTTP请求。
  • 由于默认 HttpURLConnection 没有连接池、性能和效率比较低,如果采用默认,性能上不是最牛B的,所以加到最大。

6.5.3. 替换之前,还是按照超时报错的案例

  • 修改 cloud-consumer-feign-order80 的 OrderController
    @GetMapping("/getPayInfo/{id}")
    public ResultData getPayInfo(@PathVariable("id") Integer id){

        ResultData data = null;
        try {
            System.out.println("调用开始 ===============》 " + DateUtil.now());
            data = payFeignApi.getById(id);
        } catch (Exception e) {
            System.out.println("调用结束 ===============》 " + DateUtil.now());
            throw new RuntimeException(e);
        }
        return data;
    }

6.5.4. Apache HttpClient 5替换OpenFeign默认的HttpURLConnection

修改微服务feign80:cloud-consumer-openfeign-order80

  1. 为了更快的看到效果,暂时关闭重试机制
    1. Feignconfig类里面将Retryer属性修改为默认
package com.yq.springcloud.config;

import feign.Retryer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FeignConfig {

    @Bean
    public Retryer myRetryer() {
        return Retryer.NEVER_RETRY; //Feign默认配置是不走重试策略的

        //最大请求次数为3(1+2),初始间隔时间为100ms,重试间最大间隔时间为1s
//        return new Retryer.Default(100, SECONDS.toMillis(1), 3);
    }
}

  1. POM修改
<!-- httpclient5-->
<dependency>
    <groupId>org.apache.httpcomponents.client5</groupId>
    <artifactId>httpclient5</artifactId>
    <version>5.3</version>
</dependency>
<!-- feign-hc5-->
<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-hc5</artifactId>
    <version>13.1</version>
</dependency>

  1. Apache Httpclient5配置开启说明
server:
  port: 80

spring:
  application:
    name: cloud-consumer-openfeign-order
  ####Spring Cloud Consul for Service Discovery
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        prefer-ip-address: true #优先使用服务ip进行注册
        service-name: ${spring.application.name}
    openfeign:
      client:
        config:
          default:
            #连接超时时间
            connect-timeout: 5000
            #读取超时时间
            read-timeout: 5000
          # 为cloud-payment-service这个服务单独配置超时时间,单个配置的超时时间将会覆盖全局配置
          cloud-payment-service:
            #连接超时时间
            connectTimeout: 3000
            #读取超时时间
            readTimeout: 3000
      httpclient:
        hc5:
          enabled: true

6.5.5. 替换之后

6.6. OpenFeign请求/响应压缩

6.6.1. 官网说明

6.6.2. 是什么

  1. 对请求和响应进行GZIP压缩

Spring Cloud OpenFeign支持对请求和响应进行GZIP压缩,以减少通信过程中的性能损耗。

通过下面的两个参数设置,就能开启请求与相应的压缩功能:

spring.cloud.openfeign.compression.request.enabled=true

spring.cloud.openfeign.compression.response.enabled=true

  1. 细粒度化设置

对请求压缩做一些更细致的设置,比如下面的配置内容指定压缩的请求数据类型并设置了请求压缩的大小下限,

只有超过这个大小的请求才会进行压缩:

spring.cloud.openfeign.compression.request.enabled=true

spring.cloud.openfeign.compression.request.mime-types=text/xml,application/xml,application/json #触发压缩数据类型

spring.cloud.openfeign.compression.request.min-request-size=2048 #最小触发压缩的大小

6.6.3. yml文件

server:
  port: 80

spring:
  application:
    name: cloud-consumer-openfeign-order
  ####Spring Cloud Consul for Service Discovery
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        prefer-ip-address: true #优先使用服务ip进行注册
        service-name: ${spring.application.name}
    openfeign:
      client:
        config:
          default:
            #连接超时时间
            connect-timeout: 5000
            #读取超时时间
            read-timeout: 5000
          # 为cloud-payment-service这个服务单独配置超时时间,单个配置的超时时间将会覆盖全局配置
          cloud-payment-service:
            #连接超时时间
            connectTimeout: 3000
            #读取超时时间
            readTimeout: 3000
      httpclient:
        hc5:
          enabled: true
      # 启用请求或响应的GZIP压缩
      compression:
        request:
          enabled: true
          min-request-size: 2048
          mime-types: text/xml, application/xml, application/json
        response:
          enabled: true

6.6.4. 压缩效果测试在下一章节体现(需要配日志)

6.7. OpenFeign日志打印功能

6.7.1. 官网说明

6.7.2. 是什么

Feign 提供了日志打印功能,我们可以通过配置来调整日志级别,从而了解 Feign 中 Http 请求的细节,

说白了就是对Feign接口的调用情况进行监控和输出。

6.7.3. 日志级别

  1. NONE:默认的,不显示任何日志;
  2. BASIC:仅记录请求方法、URL、响应状态码及执行时间;
  3. HEADERS:除了 BASIC 中定义的信息之外,还有请求和响应的头信息;
  4. FULL:除了 HEADERS 中定义的信息之外,还有请求和响应的正文及元数据。

6.7.4. 配置日志bean

package com.yq.springcloud.config;

import feign.Logger;
import feign.Retryer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FeignConfig {

    @Bean
    public Retryer myRetryer() {
        return Retryer.NEVER_RETRY; //Feign默认配置是不走重试策略的

        //最大请求次数为3(1+2),初始间隔时间为100ms,重试间最大间隔时间为1s
//        return new Retryer.Default(100, SECONDS.toMillis(1), 3);
    }

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

6.7.5. yml文件里需要开启日志的Feign客户端

公式(三段):logging.level + 含有@FeignClient注解的完整带包名的接口名+debug

# feign日志以什么级别监控哪个包下的接口
logging:
  level:
    com:
      yq:
        springcloud:
          apis: debug

6.7.6. 补充实验1:后台日志查看

  1. 带着压缩调用

  1. 去掉压缩调用

6.7.7. 补充实验2:重试机制控制台看到3次过程

7. OpenFeign和Sentinel集成实现fallback服务降级

  • 见后续springcloud alibaba篇章

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值