OpenFeign全称为Spring Cloud OpenFeign,是SpringCloud团队开发的一款基于Feign的框架,声明式web服务客户端。
Feign是Netflix开源的一个声明式web服务客户端,它简化了基于http的服务调用,使得服务间的通信变得更加简单和灵活,Feign通过定义接口,注解和动态代理等方式,将服务调用的过程封装起来,开发者只需要定义服务接口,而无需关心底层的http请求和序列化等细节OpenFeign是一个声明式的Web服务客户端,它让编写Web服务客户端变得非常容易。简单来说,它的主要作用是帮助你方便地调用远程服务。在微服务架构中,服务之间的通信是一个常见的需求,OpenFeign提供了一种简化的方法来实现这种通信。
通俗解释:
想象一下,你在一个大型购物中心,需要找到不同的商店去购买东西。你可能会拿一份购物中心的地图,上面标记了每个商店的位置。在这个比喻中,每个商店就像是一个独立的微服务,而地图就像是OpenFeign。你不需要知道每个商店的具体位置,只需要查看地图就可以直接到达那里。在微服务架构中,OpenFeign就像这样的地图,它知道如何找到并调用其他服务。
应用场景举例:
假设你正在构建一个在线电商平台,这个平台分为几个微服务:
用户服务:管理用户信息。
订单服务:处理订单相关的操作。
产品服务:管理产品信息。
支付服务:处理支付相关事务。
当用户在网站上下订单时,订单服务需要与用户服务确认用户信息,与产品服务检查产品库存,然后可能还要与支付服务处理支付。在没有OpenFeign的情况下,订单服务需要知道如何与这些服务通信,包括服务地址、端口号、具体的请求路径等。而使用OpenFeign,开发者只需声明式地定义服务接口,OpenFeign会自动处理服务间的通信细节。
例如,订单服务中的一个接口可能是这样的:
@FeignClient("用户服务")
public interface UserServiceClient {
@GetMapping("/users/{id}")
User getUserById(@PathVariable("id") Long userId);
}
OpenFeign在Feign的基础上提供了以下增强和扩展功能:
1.集成Spring Cloud LoadBalancer:OpenFeign整合了Spring Cloud的LoadBalancer,这意味着你可以在使用OpenFeign时享受到Spring Cloud提供的负载均衡能力。例如,如果你的服务部署了多个实例,OpenFeign可以自动帮你平衡请求负载,均匀地将请求发送到不同的服务实例。
2.Hystrix熔断器支持:OpenFeign支持Hystrix熔断器,这让服务调用更加可靠。如果被调用的服务发生故障,熔断器会暂时切断调用,防止错误蔓延。例如,如果你的服务调用了一个订单服务,但订单服务因为某些原因不可用,熔断器可以防止这种情况影响到调用方的服务。
3.声明式REST客户端:OpenFeign让你可以通过简单的声明式方法,定义RESTful服务的客户端接口。比如,你只需要定义一个接口,并用注解标明调用的服务名和路径,OpenFeign就会自动处理服务的发现和请求发送。
4.易于集成和配置:OpenFeign易于与Spring Cloud配置中心和服务注册发现等组件整合,让微服务之间的调用更加方便。例如,你可以在application.properties或application.yml中配置OpenFeign的相关参数,来控制日志级别、连接超时时间等。
5.支持@FeignClient注解:OpenFeign引入了@FeignClient注解作为Feign客户端的标识,可以方便地定义和使用远程服务的声明式接口。
1.先添加框架:Nacos Discovery 、Spring Cloud LoadBalancer、Spring Cloud OpenFeign
2.配置Nacos
3.开启OpenFeign功能
4.编写OpenFeign调用代码
5.编写代码通过OpenFeign调用生产者
在我的Nacos博客中的9.4消费者实现中有讲到,请移步去看
在微服务架构中,服务之间是通过网络进行通信的,而网络是非常复杂和不稳定的,所以在调用服务时可能会失败或者延时,那么在这种情况下,我们就需要给OpenFeign配置超时重试机制了。
什么是超时重试呢?
超时重试机制是一种常见的网络通信策略,用于处理网络请求在特定时间内未能成功完成的情况。在分布式系统或微服务架构中,由于网络延迟、服务不稳定等原因,客户端可能无法及时从服务端获取响应。超时重试机制就是为了应对这种情况而设计的。
这个机制的基本思想是:
超时设置:为网络请求设定一个超时时间。如果在这个时间内没有收到响应(或无法建立连接),系统就会认为请求超时了。
重试策略:当请求超时后,系统可以自动再次发起请求。这个过程可以进行多次,通常有一个最大重试次数的限制。
间隔控制:在重试之间,通常会设置一个时间间隔,防止频繁重试对服务端造成过大压力。
这种机制在网络不稳定或服务响应缓慢的情况下特别有用,能够提高系统的健壮性和可靠性。然而,也需要谨慎使用,因为不合理的重试策略(如重试次数过多、间隔时间过短)可能会加剧服务端的压力,甚至引起雪崩效应。
OpenFeign默认情况下是不会自动开启超时重试的,所以想要开启重试,需要通过以下两个步骤来实现:
1.设置OpenFeign超时时间(请求最大连接时间,读取时间)
2.进行重试操作(重试次数,重试的间隔时间,重试的最大间隔时间)
请求最大连接时间(Connect Timeout):这是指发起请求连接目标服务的最大等待时间。如果在这段时间内服务没有响应,连接就会被认为失败。比如设置为1000毫秒,如果连接目标服务超过这个时间还没建立起来,就会触发超时。
读取时间(Read Timeout):指从服务器获取响应数据需要等待的时间,即在成功建立连接后,客户端等待服务器返回数据的时间。如果超过这个时间还没有读取到数据,则认为读取操作超时。例如,设置为2000毫秒,如果在连接成功后,2秒内服务没有返回数据,就会触发超时。
重试次数(Max Attempts):指在发生超时或其他错误时,客户端尝试重新发送请求的次数。比如设置为3,意味着在初始请求失败后,会再尝试发送请求3次。
重试的间隔时间(Backoff Delay):这是指每次重试请求之间的等待时间。例如,如果设置为1000毫秒,那么在每次重试之间会等待1秒。
最大间隔时间(Max Backoff Delay):在有的实现中,随着重试次数的增加,间隔时间会逐渐增长,直到达到一个最大值。这个参数就是用来设置这个最大值。例如,如果最大间隔时间设置为5000毫秒,那么无论重试多少次,两次重试之间的等待时间不会超过5秒。
区别在于,请求最大连接时间和读取时间是关于单次请求连接和响应的时间限制,而重试次数、重试的间隔时间、最大间隔时间则是在请求失败后重试机制的相关设置。前两者是控制请求的及时性,后三者是在失败后的恢复策略。
1.设置OpenFeign超时时间
在你的consumer的appliaction.yml中复制下面代码
spring:
application:
name: nacos-consumer-demo
cloud:
nacos:
discovery:
server-addr: localhost:8848
username: nacos
password: nacos
register-enabled: false # 消费者(不需要将此服务注册到nacos)
openfeign:
client:
config:
default:
connect-timeout: 1000
read-timeout: 1000
server:
port: 8080
connect-timeout: 1000
connect-timeout 指的是连接超时时间,单位是毫秒。
这里设置为1000毫秒,意味着当OpenFeign客户端尝试与远程服务建立连接时,如果在1000毫秒内未能成功建立连接,则会被认为是连接超时。
read-timeout: 1000
read-timeout 是指读取超时时间,也是以毫秒为单位。
这里设置为1000毫秒,意味着一旦连接建立,如果在1000毫秒内无法从服务端读取到任何数据,那么就会被认为是读取超时。
2.开启超时重试
import feign.Retryer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RetryerConfig {
@Bean
public Retryer retryer(){
return new Retryer.Default(1000,1000,3);
}
}
1.自定义超时重试类(实现Retyrer接口,并且重写continueOrPropagate方法)
import feign.RetryableException;
import feign.Retryer;
import java.time.LocalDateTime;
/**
*自定义超时重传类
*/
public class CustomerRetryer implements Retryer {
private final int maxAttempts;//最大尝试次数
private final int period;//超时间隔次数
int attempt;//当前尝试次数
//这里只配置了三个变量,还有别的变量呢,可以自行配置
public CustomerRetryer(){
this.maxAttempts=3;
this.period= 1000;
this.attempt=0;
}
@Override
public void continueOrPropagate(RetryableException e) {
if(attempt++>=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);
}
}
@Override
public Retryer clone() {
return new CustomerRetryer();
}
}
2.设置配置文件
spring:
application:
name: nacos-consumer-demo
cloud:
nacos:
discovery:
server-addr: localhost:8848
username: nacos
password: nacos
register-enabled: false # 消费者(不需要将此服务注册到nacos)
openfeign:
client:
config:
default:
connect-timeout: 1000
read-timeout: 1000
retryer: com.example.consumer.config.CustomerRetryer
server:
port: 8080