Feign組件默認使用Ribbon的重試機制並增長了根據狀態碼判斷重試機制,默認狀況下是不啓用的。Feign使用的是Spring Retry組件,須要引入依賴才能啓用。git
<dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency>
eureka-client: ribbon: MaxAutoRetries: 1 MaxAutoRetriesNextServer: 1 retryableStatusCodes: 500,404 OkToRetryOnAllOperations: true NFLoadBalancerRuleClassName: com.netflix.loadbalancer.AvailabilityFilteringRule #負載均衡規則
eureka-client
是本身的serverId,MaxAutoRetries
同一臺服務器上的最大重試次數(不包括第一次嘗試),MaxAutoRetriesNextServer
要重試的下一個服務器的最大數量(不包括第一個服務器),retryableStatusCodes
能夠根據接口返回的狀態碼判斷是否重試其餘服務,OkToRetryOnAllOperations
只對全部的超時請求重試github
注意: Ribbon的重試機制只有對GET請求或者設置了OkToRetryOnAllOperations
生效 詳情請查看源碼:spring
public class RibbonLoadBalancedRetryPolicy implements LoadBalancedRetryPolicy { ... public boolean canRetry(LoadBalancedRetryContext context) { HttpMethod method = context.getRequest().getMethod(); return HttpMethod.GET == method || lbContext.isOkToRetryOnAllOperations(); } ... }
Feign對返回狀態碼作了重試判斷RetryableFeignLoadBalancer
json
public class RetryableFeignLoadBalancer extends FeignLoadBalancer implements ServiceInstanceChooser { ... [@Override](https://my.oschina.net/u/1162528) public RibbonResponse execute(final RibbonRequest request, IClientConfig configOverride) throws IOException { ... if (retryPolicy != null && retryPolicy.retryableStatusCode(response.status())) { byte[] byteArray = response.body() == null ? new byte[] {} : StreamUtils .copyToByteArray(response.body().asInputStream()); response.close(); throw new RibbonResponseStatusCodeException( RetryableFeignLoadBalancer.this.clientName, response, byteArray, request.getUri()); } ... } ... }
重試機制用的是Spring Retry組件當拋出異常時進行重試!服務器
GET請求指的是feign client 請求其餘client時聲明的那個interface中mapping註解類型,RequestMapping不設置method默認爲GET請求app
@FeignClient("stores") public interface StoreClient { @RequestMapping(method = RequestMethod.GET, value = "/stores") List<Store> getStores(); @RequestMapping(method = RequestMethod.POST, value = "/stores/{storeId}", consumes = "application/json") Store update(@PathVariable("storeId") Long storeId, Store store); }