Spring Cloud(3)一看就懂,Spring Cloud OpenFeign快速入门

本文深入介绍了SpringCloudOpenFeign的使用,包括快速入门、自定义配置(日志、契约、超时、HttpClient)、创建多个Feign客户端、负载均衡和熔断器支持。通过配置Feign,可以实现优雅的日志记录、自定义HTTP客户端、调整超时时间和实现认证逻辑。同时,文章还探讨了如何在OpenFeign中启用负载均衡和使用熔断器,如Hystrix,以增强系统的健壮性。
摘要由CSDN通过智能技术生成

1.OpenFeign介绍

​ 在使用 Spring Cloud 开发微服务应用时,各个服务提供者都是以 HTTP 接口的形式对外提供服务,因此在服务消费者调用服务提供者时,底层通过 HTTP Client 的方式访问。此时可以使用 JDK 原生的 URLConnection、Apache 的 HTTP Client、Netty 的异步 HTTP Client 或者 Spring 的 RestTemplate 去实现服务间的调用。但是最方便、最优雅的方式是通过 Feign 进行服务间的调用。Feign 是由 Netflix 开发的一个声明式的 Web Service 客户端,它的出现使开发 Web Service 客户端变得很简单;Feign 同时也是一款声明式、模板化的 HTTP 客户端

​ Spring Cloud OpenFeign 对 Feign 进行了二次封装,使得在 Spring Cloud 中使用 Feign 的时候,可以做到使用 HTTP 请求访问远程服务,就像调用本地方法一样的,开发者完全感知不到这是在调用远程访问,更感知不到在访问 HTTP 请求。Spring Cloud OpenFeign 增强了 Feign 的功能,使 Feign 有限支持 Spring MVC 的注解,如 @RequestMapping 等。OpenFeign 的 @FeignClient 注解可以解析 Spring MVC 的 @RequestMapping 注解下的接口

2 .快速开始

本 文 实 例 使 用 的 S p r i n g C l o u d 版 本 是 : 2020.0.4 , S p r i n g B o o t 版 本 是 : 2.5.6 本文实例使用的Spring Cloud版本是:2020.0.4,Spring Boot版本是:2.5.6 使SpringCloud2020.0.4SpringBoot2.5.6

  1. 引入依赖

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    
  2. 编写调用接口,并使用@FeignClient注解

    @FeignClient(name = "order-service-resume",path ="/order")
    public interface ResumeServuceFeignClient {
    
            @RequestMapping("/findResumeByUserId/{userId}")
            Resume findResumeByUserId(@PathVariable Long userId);
    
            @RequestMapping("/getPort")
            Integer getPort();
    }
    
    • name: 指定调用rest接口所对应的服务名称
    • path:指定调用rest接口Controller的@RequestMapping("/order")
  3. 在启动类添加@EnableFeignClients 注解

    @SpringBootApplication
    @EnableDiscoveryClient
    @EnableFeignClients  
    @LoadBalancerClients(defaultConfiguration = {LoadBalancerConfiguration.class})
    public class AutodeliverApplication8091 {
    
        public static void main(String[] args) {
    
            SpringApplication.run(AutodeliverApplication8091.class,args);
        }
    }
    
  4. 发起调用,像调用本地方法一样调用远程服务

    @Slf4j
    @RestController
    @RequestMapping("/test")
    public class AutoDeliverController {
    
        @Autowired
        ResumeServuceFeignClient feignClient;
    
        @GetMapping("/testLoadBalanced")
        public Integer getPort(){
            return feignClient.getPort();
        }
    }
    

3 OpenFeign自定义配置

3.1 日志配置

  1. 定义一个配置类,指定日志级别

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

    OpenFeign的日志级别有4种,分别是:

    • NONE:不记录任何日志(默认值)。适合生产环境。

    • BASIC:仅记录请求⽅法、URL、响应状态码以及执⾏时间。适合⽣产问题追踪

    • HEADERS:在BASIC级别的基础上,记录请求和响应的header。

    • FULL:记录请求和响应的header、body和元数据。适⽤于开发及测试环境定位问题

  2. 局部配置,让调用的微服务生效,在@FeignClient注解中指定配置类

    @FeignClient(name = "order-service",path ="/order",configuration = FeignConfig.class)
    public interface ResumeServuceFeignClient {
    
            @RequestMapping("/findResumeByUserId/{userId}")
            Resume findResumeByUserId(@PathVariable Long userId);
    
            @RequestMapping("/getPort")
            Integer getPort();
    }
    
    

    如果在FeignConfig加上@Configuration注解,则此配置全局生效,如果想要指定的微服务生效,则不能添加@Configuration注解。

  3. 在配置文件中配置

    可以通过指定feignName,实现局部配置,只让某个客户端生效。比如,只让order-service 微服务生效:

    feign:
      client:
        config:
          order-service:
            loggerLevel: full
    

    如果想要全局配置,可以指定default,,下面的配置是全局生效。

    feign:
      client:
        config:
          default:
            loggerLevel: full
    

​ 如果通过 Java 代码的方式配置过 Feign,然后又通过 application.yml 或者 application.properties 属性文件的方式配置 Feign,默认情况下属性文件中 Feign 的配置会覆盖 Java 代码的配置。但是可以通过使用参数 feign.client.default-to-properties=false 来改变 Feign 配置生效的优先级。

3.2 契约(Contract)配置

Spring Cloud在Feign的基础上做了扩展,使用SpringMVC的注解完成Feign的功能。原生的Feign是不支持SpringMVC注解的,如果你想在Spring Cloud中使用原生的注解方式来定义客户浩也是可以的,通过配置契约来改变这个配置,Spring Cloud 中默认的是 SpringMvcContract。

Spring Cloud早期版本就是用的原生Feign,随着netflix的停更替换成了openfeign

  1. 修改契约配置,支持原生Feign的注解

    public class FeignConfig {
        @Bean
        public Contract feignContract() {
            return new feign.Contract.Default();
        }
    }
    

    修改契约配置后,@FeignClient不在支持SpringMVC注解,需要使用Feign原生的注解。

3.3 超时时间配置

我们可以在默认客户端和命名客户端上配置超时。 OpenFeign 使用两个超时参数:

  • connectTimeout 连接超时时间,默认2s
  • readTimeout 请求处理超时时间,默认5s

以下是在默认客户端配置,全局生效:

feign:
  client:
    config:
      default:
        connectTimeout: 5000  #连接超时时间,默认2s
        readTimeout: 2000   # 请求处理超时时间,默认5s
        loggerLevel: basic

在Java类中配置超时时间:

@Bean
public Request.Options options(){
    return new Request.Options(5000,10000);
}

3.4 Feign 默认 Http Client 修改

Feign 在默认情况下使用的是 JDK 原生的 URLConnection 发送 HTTP 请求,没有使用连接池。

Feign支持以下Http请求客户端:

  • OkHttpClient :通过 feign.okhttp.enabled=true 配置开启
  • ApacheHttpClient: 通过 feign.httpclient.enabled=true配置开启
  • ApacheHC5 :通过feign.httpclient.hc5.enabled=true 配置开启

使用 Apache HTTP Client 替换 Feign 默认的 Client

替换步骤非常简单,只需要在 pom.xmlapplication.yml 分别添加以下配置内容即可:

  • 添加依赖:
<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-httpclient</artifactId>
</dependency>
  • 添加配置

    feign:
      httpclient:
        enabled: true
    

3.5 创建多个具有相同名称或 url 的 feign 客户端

如果我们想创建多个具有相同名称或 url 的 feign 客户端,以便它们指向同一服务器但每个具有不同的自定义配置,那么我们必须使用 @FeignClientcontextId 属性以避免这些配置的名称冲突Bean。

@FeignClient(contextId = "fooClient", name = "stores", configuration = FooConfiguration.class)
public interface FooClient {
    //..
}

@FeignClient(contextId = "barClient", name = "stores", configuration = BarConfiguration.class)
public interface BarClient {
    //..
}

也可以将 FeignClient 配置为不从父上下文继承 bean。您可以通过覆盖 FeignClientConfigurer bean 中的 inheritParentConfiguration() 以返回 false 来实现此目的:

@Configuration
public class CustomConfiguration{

@Bean
public FeignClientConfigurer feignClientConfigurer() {
            return new FeignClientConfigurer() {

                @Override
                public boolean inheritParentConfiguration() {
                    return false;
                }
            };

        }
}

3.6 自定义拦截器实现认证逻辑

  1. 实现RequestInterceptor 接口

    public class FeignAuthRequestInterceptor implements RequestInterceptor {
    
        @Override
        public void apply(RequestTemplate requestTemplate) {
    
            //模拟token
            String access_token= UUID.randomUUID().toString();
            //在head中添加authorization参数
            requestTemplate.header("authorization",access_token);
        }
    }
    
  2. 在配置类中加入自定义的拦截器

    public class FeignConfig {
        /**
         * 添加自定义拦截器
          * @return
         */
          public FeignAuthRequestInterceptor feignAuthRequestInterceptor(){
              return new FeignAuthRequestInterceptor();
          }
    }
    

@FeignClient(name = "order-service-resume",path ="/order",configuration = FeignConfig.class)
public interface ResumeServuceFeignClient {

        @RequestMapping("/getPort")
        Integer getPort();


}

4 Feign负载均衡

spring-cloud-starter-openfeign 支持 spring-cloud-starter-loadbalancer。但是,作为一个可选的依赖项,如果您想使用它,您需要确保将其添加到您的项目中。

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

在最新版的Openfeign中,默认已经不再支持Ribbon负载均衡器,需要使用官方开发的loadbalancer

在项目开发中需要注意:(我这里使用的版本是:Spring Cloud版本是:2020.0.4,Spring Boot版本是:2.5.6)

  • 如果项目中,使用了Eureka作为注册中心,

    spring-cloud-starter-netflix-eureka-client,中包含了spring-cloud-starter-loadbalancer的依赖,如果已经引入了eureka组件,可以不用单独引入spring-cloud-starter-loadbalancer

  • 如果使用阿里巴巴的Nacos作为注册中心:(spring-cloud-alibaba 版本是:2.2.6.RELEASE)

    spring-cloud-starter-alibaba-nacos-discovery默认使用Ribbon负载均衡,在使用OpenFeign的时候需要单独引入spring-cloud-starter-loadbalancer ,同时还需要排除掉nacos中的Ribbon,不然项目启动会报错。

    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        <exclusions>
            <exclusion>
                <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
                <groupId>org.springframework.cloud</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    

默认的负载均衡算法为RoundRobinLoadBalancer (轮询)

关于loadbalancer的使用方法,可以参考我的另外一篇博文:https://blog.csdn.net/warybee/article/details/121284159?spm=1001.2014.3001.5501

5 Feign 熔断器支持

Spring Cloud熔断器提供了跨不同断路器抽象的实现,支持如下熔断器:

在OpenFeign中使用熔断器,也很简单,下面以Hystrix为例。

关于Hystrix的详细使用,可以参考我的另一篇博文:https://blog.csdn.net/warybee/article/details/121284365?spm=1001.2014.3001.5501

  1. 添加Hystrix依赖

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        <version>2.2.9.RELEASE</version>
    </dependency>
    
  2. 在配置文件中开启feign.circuitbreaker.enabled=true

    feign:
      client:
        config:
          default:
            connectTimeout: 5000  #连接超时时间,默认2s
            readTimeout: 2000   # 请求处理超时时间,默认5s
            loggerLevel: basic
      circuitbreaker:    #开启断路器
        enabled: true
    
  3. 自定义fallback

    @FeignClient(name = "stock-service",path = "stock",fallback = StockFeignClientFallback.class )
    public interface StockFeignClient {
    
        @RequestMapping("getPort")
        public Integer getPort();
    
    }
    
    @Component
    public class StockFeignClientFallback implements StockFeignClient {
    
        @Override
        public Integer getPort() {
            return -1;
        }
    }
    

OpenFeign 熔断器官网文档:https://docs.spring.io/spring-cloud-openfeign/docs/current/reference/html/#spring-cloud-feign-circuitbreaker

Spring Cloud 熔断器官网文档:https://spring.io/projects/spring-cloud-circuitbreaker

6 Feign的配置属性

可以在 application.properties 文件、application.yml 文件或命令行开关中指定各种属性。本附录提供了常见 Spring Cloud OpenFeign 属性的列表以及对使用它们的底层类的引用。

名称默认值描述
feign.autoconfiguration.jackson.enabledfalse如果为 true,将为 Jackson 页面解码提供 PageJacksonModule 和 SortJacksonModule bean。
feign.circuitbreaker.enabledfalse如果为 true,则 OpenFeign 客户端将使用 Spring Cloud CircuitBreaker 断路器包装。
feign.circuitbreaker.group.enabledfalse如果为 true,则 OpenFeign 客户端将使用带有组的 Spring Cloud CircuitBreaker 断路器包装。
feign.client.config
feign.client.decode-slashtrueFeign 客户端默认不编码斜杠/字符。要更改此行为,请将 decodeSlash 设置为 false。
feign.client.default-configdefault
feign.client.default-to-propertiestrue
feign.client.refresh-enabledfalse为 Feign 启用选项值刷新功能。
feign.compression.request.enabledfalse使 Feign 发送的请求能够被压缩。
feign.compression.request.mime-types[text/xml, application/xml, application/json]支持的 MIME 类型列表。
feign.compression.request.min-request-size2048最小阈值内容大小。
feign.compression.response.enabledfalse使来自 Feign 的响应能够被压缩。
feign.compression.response.useGzipDecoderfalse启用要使用的默认 gzip 解码器。
feign.encoder.charset-from-content-typefalse指示字符集是否应从 {@code Content-Type} 标头派生。
feign.httpclient.connection-timeout2000
feign.httpclient.connection-timer-repeat3000
feign.httpclient.disable-ssl-validationfalse
feign.httpclient.enabledtrue允许 Feign 使用 Apache HTTP 客户端。
feign.httpclient.follow-redirectstrue
feign.httpclient.hc5.enabledfalse允许 Feign 使用 Apache HTTP Client 5。
feign.httpclient.hc5.pool-concurrency-policy池并发策略。
feign.httpclient.hc5.pool-reuse-policy池连接重用策略。
feign.httpclient.hc5.socket-timeout5Socket超时的默认值。
feign.httpclient.hc5.socket-timeout-unitSocket超时单位的默认值。
feign.httpclient.max-connections200
feign.httpclient.max-connections-per-route50
feign.httpclient.time-to-live900
feign.httpclient.time-to-live-unit
feign.metrics.enabledtrue为 Feign 启用指标功能。
feign.okhttp.enabledfalse允许 Feign 使用 OK HTTP Client。

参考:https://docs.spring.io/spring-cloud-openfeign/docs/current/reference/html/

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

warybee

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值