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相关的主要流程(重点类和重要方法)总结如下: