一、問題:
生產環境服務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相關的主要流程(重點類和重要方法)總結如下: