Feign和OpenFeign介绍
Feign集成了Ribbon、RestTemplate实现了负载均衡的执行Http调用,只不过对原有的方式(Ribbon+RestTemplate)进行了封装,开发者不必手动使用RestTemplate调服务,而是定义一个接口,在这个接口中标注一个注解即可完成服务调用,这样更加符合面向接口编程的宗旨,简化了开发。
但遗憾的是Feign现在停止迭代了。:OpenFeign是springcloud在Feign的基础上支持了SpringMVC的注解,如@RequestMapping
等等。OpenFeign的@FeignClient
可以解析SpringMVC的@RequestMapping
注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。
OpenFeign设置超时
前面简单介绍了Feign和OpenFeign的关系,言归正传,接下来我们看看OpenFeign如何设置调用超时,openFeign其实是有默认的超时时间的,默认分别是连接超时时间10秒
、读超时时间60秒
,源码在feign.Request.Options#Options()
这个方法中。
public static class Options {
private final int connectTimeoutMillis;
private final int readTimeoutMillis;
public Options(int connectTimeoutMillis, int readTimeoutMillis) {
this.connectTimeoutMillis = connectTimeoutMillis;
this.readTimeoutMillis = readTimeoutMillis;
}
public Options() {
this(10 * 1000, 60 * 1000);
}
/**
* Defaults to 10 seconds. {@code 0} implies no timeout.
*
* @see java.net.HttpURLConnection#getConnectTimeout()
*/
public int connectTimeoutMillis() {
return connectTimeoutMillis;
}
/**
* Defaults to 60 seconds. {@code 0} implies no timeout.
*
* @see java.net.HttpURLConnection#getReadTimeout()
*/
public int readTimeoutMillis() {
return readTimeoutMillis;
}
}
openFeign集成了Ribbon,Ribbon的默认超时连接时间、读超时时间都是是1秒,源码在org.springframework.cloud.openfeign.ribbon.FeignLoadBalancer#execute()
方法中
@Override
public RibbonResponse execute(RibbonRequest request, IClientConfig configOverride)
throws IOException {
Request.Options options;
if (configOverride != null) {
options = new Request.Options(
configOverride.get(CommonClientConfigKey.ConnectTimeout,
this.connectTimeout),
(configOverride.get(CommonClientConfigKey.ReadTimeout,
this.readTimeout)));
}
else {
options = new Request.Options(this.connectTimeout, this.readTimeout);
}
Response response = request.client().execute(request.toRequest(), options);
return new RibbonResponse(request.getUri(), response);
}
源码大致意思:如果openFeign没有设置对应得超时时间,那么将会采用Ribbon的默认超时时间。理解了超时设置的原理,由之产生两种方案也是很明了
1、设置Ribbon的超时时间(不推荐)
设置很简单,在配置文件中添加如下设置:
ribbon.ConnectTimeout=60000
ribbon.ReadTimeout=60000
2、设置openFeign的超时时间(推荐)
openFeign设置超时时间非常简单,只需要在配置文件中配置,如下:
feign.client.config.default.connectTimeout=60000
feign.client.config.default.readTimeout=60000
default设置的是全局超时时间,对所有的openFeign接口服务都生效,但是正常的业务逻辑中可能涉及到多个openFeign接口的调用,如下图:
上图中的伪代码如下:
public T invoke(){
//1. 调用serviceA
serviceA();
//2. 调用serviceB
serviceB();
//3. 调用serviceC
serviceC();
}
那么上面配置的全局超时时间能不能通过呢?很显然是serviceA
、serviceB
能够成功调用,但是serviceC
并不能成功执行,肯定报超时。此时我们可以给serviceC
这个服务单独配置一个超时时间,配置如下:
feign.client.config.default.connectTimeout=1000
feign.client.config.default.readTimeout=1000
feign.client.config.ServiceC.connectTimeout=30000
feign.client.config.ServiceC.readTimeout=30000
单个配置的超时时间将会覆盖全局配置。 看到这里,不知道大家清不清楚请求调用为啥要设置超时,不设置请求超时会有啥问题?欢迎评论区交流。