一次线上超时问题,看Ribbon 超时机制

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

一、线上问题

项目上线后一段时间内运行都没有问题突然运营人员说某个接口一直失败。遂查看线上日志

spring-cloud-openfeign 通过服务名调用的服务发现没有找到可用服务实例这是第一反应应为没有看到目标 IP 这个想法通过另外一个ping 接口调用被推翻了于是怀疑是超时参数设置问题。

默认参数一定是有的而且我的 OkhttpClient 对象已经设置了超时

@Configuration
@ConditionalOnClass({Feign.class})
@AutoConfigureBefore({FeignAutoConfiguration.class})
public class OKHttpConfig {
    @Value("${feign.okhttp.maxidleConnections}")
    private Integer maxidleConnections;
    @Value("${feign.okhttp.keepAliveDuration}")
    private Integer keepAliveDuration;

    public OKHttpConfig() {
    }

    @Bean
    @LoadBalanced
    public OkHttpClient okHttpClient() {
        return (new OkHttpClient()).newBuilder().retryOnConnectionFailure(true).connectionPool(this.pool()).connectTimeout(100000L, TimeUnit.SECONDS).readTimeout(100000L, TimeUnit.SECONDS).writeTimeout(100000L, TimeUnit.SECONDS).build();
    }

    @Bean
    public ConnectionPool pool() {
        return new ConnectionPool(this.maxidleConnections, (long)this.keepAliveDuration, TimeUnit.MINUTES);
    }
}

按照推测明显这个没起作用所以只能去看下具体调用时超时参数到底是怎么起作用的

二、源码剖析

Ribbon 作为负载均衡调用 openFeign。会涉及到两个超时一个是 Ribbon 的超时设置一个是 openFeign 底层使用的 delegate 的超时。比如 httClient 或者 OkhttpClient。

下面看下这两个超时参数的设置方法

# 注意这里对应的 org.springframework.cloud.openfeign.FeignClientProperties并不是直接给 okhttp 使用的会覆盖 okhttpClient 对象构造时设置的超时参数
feign:
  client:
    config:
      default:
        connect-timeout: 20000
        read-timeout: 20000
  httpclient:
    enabled: false
  okhttp:
    enabled: true
    maxidleConnections: 150
    keepAliveDuration: 10

ribbon:
  ConnectTimeout: 5000
  ReadTimeout: 10000    

这两个参数同时设置或者只设置一个时到底会怎么作用呢通过源码我们去了解下

通过上面的代码可以看出如果没有显式配置 configOverride会使用 默认的 1s 所以线上随着数据量的增加接口一旦返回慢一点就会报超时错误

 

Ribbon 的默认配置在下面这里

如果上面图看的有点晕那下面这张图一定让你茅塞顿开

总结一句话 Feign 集成了 Ribbon 通过 LoadBalancerFeignClient 直接调用而 LoadBalancerFeignClient 又通过代理 OkhttpClient 这里是feign包里的继续往下代理会调用真正的 okhttp3.OkHttpClient。

参数配置优先级feign 没有配置会使用ribbon的否则会使用 feign 配置的如果feign 配置的和 okhttp3.OkHttpClient 参数不一致会使用 feign 配置的

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6