一次feign调用流程:
1.--->注解@feignclient被包装成FeignClientFactoryBean
2.---> HystrixInvocationHandler.invoke
3.--->HystrixCommand.run
4.--->SynchronousMethodHandler.invoke
5.--->DependencyFeignClientAutoConfiguration.dependencyBasedFeignClient得到LoadBalancerFeignClient后
6.--->LoadBalancerFeignClient.execute : 里面有个delegate=Client.Default
7.--->feignLoadBalancer.executeWithLoadBalancer (做一些ribbon负载均衡处理,选择一个server)
a、创建LoadBalancerCommand command = buildLoadBalancerCommand(request, requestConfig)会指定重试RequestSpecificRetryHandler调用AbstractLoadBalancingClient.getRequestSpecificRetryHandler,代码如下:
@Override
public RequestSpecificRetryHandler getRequestSpecificRetryHandler(
final S request, final IClientConfig requestConfig) {
if (this.okToRetryOnAllOperations) {
return new RequestSpecificRetryHandler(true, true, this.getRetryHandler(),
requestConfig);
}
if (!request.getContext().getMethod().equals("GET")) {//如果是post请求默认okToRetryOnAllErrors=false
return new RequestSpecificRetryHandler(true, false, this.getRetryHandler(),
requestConfig);
}
else {// 如果是get请求默认okToRetryOnAllErrors=true,这里就导致get请求超时会重试一次
return new RequestSpecificRetryHandler(true, true, this.getRetryHandler(),
requestConfig);
}
}
b.超时异常重试会判断重试策略,进而判断异常是不是可重试的异常,代码如下:
private Func2 retryPolicy(final int maxRetrys, final boolean same) {
return new Func2() {
@Override
public Booleancall(Integer tryCount, Throwable e) {
if (einstanceof AbortExecutionException) {
return false;
}
if (tryCount >maxRetrys) {
return false;
}
if (e.getCause() !=null && einstanceof RuntimeException) {
e = e.getCause();
}
return retryHandler.isRetriableException(e, same);
}
};
}
c.判断异常是不是可重试的异常,调用RequestSpecificRetryHandler.isRetriableException
@Override
public boolean isRetriableException(Throwable e, boolean sameServer) {
if (okToRetryOnAllErrors) {
return true;
}
else if (einstanceof ClientException) {
ClientException ce = (ClientException) e;
if (ce.getErrorType() == ClientException.ErrorType.SERVER_THROTTLED) {
return !sameServer;
}else {
return false;
}
}
else {
return okToRetryOnConnectErrors && isConnectionException(e);
}
}
8.--->LoadBalancerCommand.submit(ServerOperation operation) ---->operation.call{---------包含重试逻辑
AbstractLoadBalancerAwareClient.this.execute(requestForServer, requestConfig) ------------选择好server后,调用委托实例delegate的Client.execute方法,这时才是真正调用http请求
}