目录
一、什么是 OpenFeign?
1.1 OpenFeign 功能升级
二、OpenFeign超时重试机制
2.1 超时重试机制
2.2 自定义超时重试机制
2.2.2 自定义超时重试类
2.3 OpenFeign 超时重试的底层原理
一、什么是 OpenFeign?
OpenFeign 的全称为 Spring Cloud OpenFeign(下文简称 Openfeign),是 Spring Cloud 团队开发的-款基于 Feign 的框架,声明式 Web 服务客户端。
Feign 是 Netflix 开源的一个声明式的 Web 服务客户端,它简化了基于 HTTP 的服务调用,使得服务间的通信变得更加简单和灵活。Feign 通过定义接口、注解和动态代理等方式,将服务调用的过程封装起来,开发者只需要定义服务接口,而无需关心底层的 HTTP 请求和序列化等细节。
1.1 OpenFeign 功能升级
OpenFeign 在 Feign 的基础上提供了以下增强和扩展功能:
- 更好的集成 Spring Cloud 组件:OpenFeign 与 Spring Cloud 其他组件(如服务发现、负载均衡1.等)紧密集成,可以无缝地与其他 Spring Cloud 组件一起使用。
- 支持 @FeignClient 注解:OpenFeign 引入了 @FeignClient 注解作为 Feign 客户端的标识,可以方便地定义和使用远程服务的声明式接口。
- 错误处理改进:OpenFeign 对异常的处理做了增强,提供了更好的错误信息和异常处理机制,使得开发者可以更方便地进行错误处理。例如 OpenFeign 提供的错误解码器(DefaultErrorDecoder)和回退策略(当服务端返回错误响应或请求失败时,OpenFeiqn 会调用回退策略中的逻辑,提供一个默认的处理结果)。
- 更丰富的配置项:OpenFeign 提供了丰富的配置选项,可以对 Feign 客户端的行为进行灵活的配置,例如超时设置、重试策略等。
前两点就不必多说,对于三四两点,我们可以展开聊聊,第三点错误处理改进,可以让我们在运行SpringCloud项目的情况下,通过SkyWalking可以更精确的发现和修改错误。
关于OpenFeign的基本使用,博主在上一篇入门与实战Nacos系列的消费者实现模块已经说明:
SpringCloud之Nacos入门与实战系列-CSDN博客,因此我们这篇博客主要讲将OpenFeign的超时重试机制和自定义超时重试机制。
二、OpenFeign超时重试机制
2.1 超时重试机制
在微服务架构中,服务之间是通过网络进行通信的,而网络是非常复杂性和不稳定的,所以在调用服务时可能会失败或超时,那么在这种情况下,我们就需要给 OpenFeign 配置超时重试机制了。
什么是超时重试?
答:超时重试是一种在网络通信中常用的策略,用于处理请求在一定时间内未能得到响应或得到超时响应的情况。当发起请求后,如果在规定的时间内没有得到预期的响应,就会触发超时重试机制,重新发送请求。
超时重试的主要目的是提高请求的可靠性和稳定性,以应对网络不稳定、服务不可用、响应延迟等不确定因素。
OpenFeign 默认情况下是不会自动开启超时重试的,所以想要开启超时重试,需要通过以下2 步来实现:
- 配置超时重试
- 覆盖 Retryer 对象
覆盖超时重试
spring:cloud:openfeign:client:config:default: # 全局配置connect-timeout: 1000 # 连接超时时间 1sread-timeout: 1000 # 读取超时时间 1s
覆盖 Retryer 对象
package com.example.consumer.config;import feign.Retryer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class RetryerConfig {@Beanpublic Retryer retryer() {return new Retryer.Default(1000,3000,3);}
}
观察源码,我们可以发现:默认提供的Default对象,最大尝试次数一开始就是1,那也就是说,我们刚刚设置最大重试次数为3,那么其实只会重试2次,因为第一次也被算进去了。
每次尝试之后,会进行+1操作:
2.2 自定义超时重试机制
2.2.2 自定义超时重试类
常见的超时重试策略有以下三种:
- 固定间隔重试:每次重试之间的时间间隔固定不变,例如每次重试之间相隔 1秒。
- 指数重试:每次重试之间的时间间隔按指数递增。例如,初始间隔为1秒,每次重试后加倍,即第2.一次 1 秒,第二次 2 秒,第三次 4秒,以此类推。
- 随机间隔重试:每次重试之间的时间间隔是随机的,通过引入随机性来防止多个失败请求同时发生。例如,每次重试的时间间隔在一定范围内随机选择。
package com.example.consumer.config;import feign.RetryableException;
import feign.Retryer;import java.time.LocalDateTime;public class CustomRetryer implements Retryer {private final int maxAttempts; //最大尝试次数private final long period; // 重试间隔时间private int attempt; // 当前尝试次数public CustomRetryer() {maxAttempts = 3;attempt = 1;period = 1000;}@Overridepublic void continueOrPropagate(RetryableException e) {if (this.attempt++ >= this.maxAttempts) {throw e;}long interval = this.period;System.out.println(LocalDateTime.now() + "| 执行一次重试:" + interval);try {Thread.sleep(interval*(attempt));} catch (InterruptedException ex) {throw new RuntimeException(ex);}}@Overridepublic Retryer clone() {return null;}
}
设置配置文件:
spring:application:name: nacos-consumer-demo # 注意这里填写的是服务名 (并且命名不要使用 下划线_)cloud:nacos:discovery:server-addr: localhost:8848username: nacospassword: nacosregister-enabled: false # 由于是消费者,所以这里不进行注册到注册中心openfeign:client:config:default: # 全局配置connect-timeout: 3000 # 连接超时时间 2sread-timeout: 1000 # 读取超时时间 1sretryer: com.example.consumer.config.RetryerConfig # 自定义失败重试类
server:port: 8080 # 作为消费者,那就需要设置一个固定的端口号,
2.3 OpenFeign 超时重试的底层原理
该模块是照搬OpenFeign 的超时重试机制以及底层实现原理_openfeign重试机制-CSDN博客作为自己学习的记录。
① 加注解
在启动类或者配置类上添加 @EnableFeignClients注解
② 动态代理
这个注解会触发Spring框架的自动配置机制,扫描所有标记有@FeignClient的接口,并为它们创建代理实例
③ RequestTemplate 发送HTTP请求
此处的 RequeustTemplate 我们可以理解为 RestTemplate,因为他俩的目的相同。OpenFeign 不能直接发送 HTTP 请求,它在动态代理里面做了一件事,它将注解里面请求的路由地址拿出来,然后就能拼出来一个 URL 请求的地址,然后再使用 RequestTemplate(RestTemplate)去发送 HTTP 请求。
④ RestTemplate 依靠 HTTP 框架实现 web 请求 (把它理解为 RestTemplate)
RestTemplate 只是一个模板方法类,它只是规定了一个调用的 API,它底层并没有实现,它依靠的是 HTTP 框架实现的 web 请求 (阿帕奇的 HttpClient 框架)