一文詳解Spring Cloud Feign重試機制

前言

Feign組件默認使用Ribbon的重試機制並增長了根據狀態碼判斷重試機制,默認狀況下是不啓用的。Feign使用的是Spring Retry組件,須要引入依賴才能啓用。spring

1、POM引入Spring Retry

<dependency>
        <groupId>org.springframework.retry</groupId>
        <artifactId>spring-retry</artifactId>
  </dependency>

2、配置文件

eureka-client:
   ribbon:
      MaxAutoRetries: 1
      MaxAutoRetriesNextServer: 1
      retryableStatusCodes: 500,404 
      OkToRetryOnAllOperations: true 
      NFLoadBalancerRuleClassName: com.netflix.loadbalancer.AvailabilityFilteringRule #負載均衡規則

eureka-client是本身的serverId,MaxAutoRetries同一臺服務器上的最大重試次數(不包括第一次嘗試),MaxAutoRetriesNextServer要重試的下一個服務器的最大數量(不包括第一個服務器),retryableStatusCodes能夠根據接口返回的狀態碼判斷是否重試其餘服務,OkToRetryOnAllOperations只對全部的超時請求重試json

注意: Ribbon的重試機制只有對GET請求或者設置了OkToRetryOnAllOperations生效 詳情請查看源碼:服務器

public class RibbonLoadBalancedRetryPolicy implements LoadBalancedRetryPolicy {
	...
		public Boolean canRetry(LoadBalancedRetryContext context) {
		HttpMethod method = context.getRequest().getMethod();
		return HttpMethod.GET == method || lbContext.isOkToRetryOnAllOperations();
	}
	...
}

Feign對返回狀態碼作了重試判斷RetryableFeignLoadBalancerapp

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請求ide

@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);
}

寫在最後

  • 第一:看完點贊,感謝您對做者的承認;
  • ...
  • 第二:隨手轉發,分享知識,讓更多人學習到;
  • ...
  • 第三:記得點關注,天天更新的!!!
  • ...

相關文章
相關標籤/搜索