Feign 失败降级未生效和超时配置优先级问题

一、问题:

生产环境服务A 通过feign调用 服务B,服务A报警信息如下:

详细分析发现问题

(1)服务A调用服务B失败,未触发声明的失败降级操作

(2)同时配置ribbon和feign超时时间,优先级问题

feign:
  client:
    config:
      pay-service: # 对服务提供者(优先级高):填对应服务提供者名称,
                         # 对所有提供者(优先级低):固定"default"
        connectTimeout: 3000 # 连接超时时间单位ms
        readTimeout: 8000  # 读取超时时间单位ms
ribbon:
  ReadTimeout: 60000 #ribbon连接超时
  ConnectTimeout: 60000 #ribbon读取超时

二、解决:

针对上述问题(1) (2)通过源码debug分析得出结论分别如下

(1)Feign降级生效配置:

feign:
  hystrix:
    enabled: true

(2)超时时间(feign的优先级高于ribbon):

同时配置ribbon和feign。feign会覆盖ribbon,详细代码见 LoadBalancerFeignClient类的如下方法

 1 @Override
 2 public Response execute(Request request, Request.Options options) throws IOException {
 3    try {
 4       URI asUri = URI.create(request.url());
 5       String clientName = asUri.getHost();
 6       URI uriWithoutHost = cleanUrl(request.url(), clientName);
 7       FeignLoadBalancer.RibbonRequest ribbonRequest = new FeignLoadBalancer.RibbonRequest(
 8             this.delegate, request, uriWithoutHost);
 9 
10       IClientConfig requestConfig = getClientConfig(options, clientName);
11       return lbClient(clientName).executeWithLoadBalancer(ribbonRequest,
12             requestConfig).toResponse();
13    }
14    catch (ClientException e) {
15       IOException io = findIOException(e);
16       if (io != null) {
17          throw io;
18       }
19       throw new RuntimeException(e);
20    }
21 }

第10行 Request.Options 为feign设置超时时间属性。会首先feign超时时间构造IClientConfig 

第11行首先 lbClient(clientName)构造RetryableFeignLoadBalancer对象,然后executeWithLoadBalancer方法中会重新注入上一步生成的IClientConfig 

所以feign会覆盖ribbon的配置,优先级更高

三、源码分析:

知其然并知其所以然,Feign相关的主要流程(重点类和重要方法)总结如下:

 

posted @ 2019-11-20 15:36  浮生若云  阅读(2263)  评论(0编辑  收藏  举报