OpenFegin源码分析-4

Feign调用逻辑 未开启hystris

ReflectiveFeign静态内部类实现了InvocationHandler接口 当调用feign接口时候 会进入invoke方法

public class ReflectiveFeign{
 static class FeignInvocationHandler implements InvocationHandler {
  //代理的目标类HardCodedTarget
  private final Target target;
  //方法以及 方法的处理器 处理器实现类为 SynchronousMethodHandler
  private final Map<Method, MethodHandler> dispatch;

  FeignInvocationHandler(Target target, Map<Method, MethodHandler> dispatch) {
    this.target = checkNotNull(target, "target");
    this.dispatch = checkNotNull(dispatch, "dispatch for %s", target);
  }

  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
      //对obeject中的方法进行判断和返回
    if ("equals".equals(method.getName())) {
      try {
        Object otherHandler =
            args.length > 0 && args[0] != null ? Proxy.getInvocationHandler(args[0]) : null;
        return equals(otherHandler);
      } catch (IllegalArgumentException e) {
        return false;
      }
    } else if ("hashCode".equals(method.getName())) {
      return hashCode();
    } else if ("toString".equals(method.getName())) {
      return toString();
    }
    //从dispatch的map中获取method,调用method中的invoke方法 (SynchronousMethodHandler类中的invoke方法)
    return dispatch.get(method).invoke(args);
  }
}
}

SynchronousMethodHandler invoke方法

@Override
public Object invoke(Object[] argv) throws Throwable {
    //将参数中的args 填充到之前解析的模版中
  RequestTemplate template = buildTemplateFromArgs.create(argv);
  //发现参数中 options类型 
  Options options = findOptions(argv);
  //retryer copy创建
  Retryer retryer = this.retryer.clone();
  while (true) {
    try {
        //执行http请求 解码数据 返回
      return executeAndDecode(template, options);
    } catch (RetryableException e) {
      try {
        retryer.continueOrPropagate(e);
      } catch (RetryableException th) {
        Throwable cause = th.getCause();
        if (propagationPolicy == UNWRAP && cause != null) {
          throw cause;
        } else {
          throw th;
        }
      }
      if (logLevel != Logger.Level.NONE) {
        logger.logRetry(metadata.configKey(), logLevel);
      }
      continue;
    }
  }
}

SynchronousMethodHandler executeAndDecode方法

Object executeAndDecode(RequestTemplate template, Options options) throws Throwable {
    //添加RequestInterceptor请求拦截器
  Request request = targetRequest(template);
  Response response;
  //设置请求开始时间
  long start = System.nanoTime();
  try {
      //执行调用获取 resonpse 调用LoadBalancerFeignClient的execute方法
    response = client.execute(request, options);
  } catch (IOException e) {
    //出现io异常直接抛出
    throw errorExecuting(request, e);
  }
  //记录请求响应的时间
  long elapsedTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);
  //是否应该关闭响应体 默认为true 
  boolean shouldClose = true;
  try {
    //先判断response类型 如何和之前解析出来的类型一直 直接返回
    if (Response.class == metadata.returnType()) {
      if (response.body() == null) {
        return response;
      }
      if (response.body().length() == null ||
          response.body().length() > MAX_RESPONSE_BUFFER_SIZE) {
              //如果返回的body的长度 >8192L 响应体直接返回
        shouldClose = false;
        return response;
      }
      // 响应体没有断开 直接解析成 byte数组返回
      byte[] bodyData = Util.toByteArray(response.body().asInputStream());
      return response.toBuilder().body(bodyData).build();
    }
    //如果返回值和之前解析到的不一致 成功请求处理
    if (response.status() >= 200 && response.status() < 300) {
        //http请求为成功
      if (void.class == metadata.returnType()) {
          //返回值类型为void 直接返回null
        return null;
      } else {
          //对返回提body进行解码处理,
        Object result = decode(response);
        //构建feign时为默认值 true
        shouldClose = closeAfterDecode;
        return result;
      }
    }
    //404请求处理decode404 为true 
     else if (decode404 && response.status() == 404 && void.class != metadata.returnType()) {
      Object result = decode(response);
      shouldClose = closeAfterDecode;
      return result;
    } 
    //其他状态码直接 解析完抛出异常
    else {
        //抛出一个RetryableException 异常 外层方法捕获后处理
      throw errorDecoder.decode(metadata.configKey(), response);
    }
  } catch (IOException e) {
    throw errorReading(request, response, e);
  } finally {
      //关闭reponse响应体
    if (shouldClose) {
      ensureClosed(response.body());
    }
  }
}

LoadBalancerFeignClient中的 execute方法

@Override
public Response execute(Request request, Request.Options options) throws IOException {
   try {
       //进行url转换 String类型转换成URI类型
      URI asUri = URI.create(request.url());
      //获取服务名称 也就是feign注解配置的name
      String clientName = asUri.getHost();
      //将uri中的host清除掉 变成 http:///path 这种格式
      URI uriWithoutHost = cleanUrl(request.url(), clientName);
      //创建RibbonRequest请求对象 主要有3个参数 http代理类 默认为java的http调用,uri参数,以及feign.request读喜庆
      FeignLoadBalancer.RibbonRequest ribbonRequest = new FeignLoadBalancer.RibbonRequest(
            this.delegate, request, uriWithoutHost);
      //获取Options 配置
      IClientConfig requestConfig = getClientConfig(options, clientName);
      //lbClient(clientName)
      return lbClient(clientName)
            .executeWithLoadBalancer(ribbonRequest, requestConfig).toResponse();
   }
   catch (ClientException e) {
      IOException io = findIOException(e);
      if (io != null) {
         throw io;
      }
      throw new RuntimeException(e);
   }
}

CachingSpringLoadBalancerFactory 中create方法(在 FeignRibbonClientAutoConfiguration自动装配类中 自动注入)

//获取负载均衡feignloadBalancer
public FeignLoadBalancer create(String clientName) {
    //从缓存中获取 缓存类型为ConcurrentReferenceHashMap 
   FeignLoadBalancer client = this.cache.get(clientName);
   if (client != null) {
      return client;
   }
   //没有获取到缓存类型直接从SpringClientFactory中获取
   // 最终走到NamedContextFactory 中获取如果存在直接返回 不存在反射创建
   IClientConfig config = this.factory.getClientConfig(clientName);
   ILoadBalancer lb = this.factory.getLoadBalancer(clientName);
   //获取端口
   ServerIntrospector serverIntrospector = this.factory.getInstance(clientName,
         ServerIntrospector.class);
         //创建client放入缓存中
   client = this.loadBalancedRetryFactory != null
         ? new RetryableFeignLoadBalancer(lb, config, serverIntrospector,
               this.loadBalancedRetryFactory)
         : new FeignLoadBalancer(lb, config, serverIntrospector);
   this.cache.put(clientName, client);
   return client;
}

AbstractLoadBalancerAwareClient 中submit方法 和executeWithLoadBalancer 方法(参数传递方式)

public Observable<T> submit(final ServerOperation<T> operation) {
    //请求上下文对象 里面包含server 服务调用量 以及服务调用总量?
    final ExecutionInfoContext context = new ExecutionInfoContext();
    //一般情况为null
    if (listenerInvoker != null) {
        try {
            listenerInvoker.onExecutionStart();
        } catch (AbortExecutionException e) {
            return Observable.error(e);
        }
    }
    //在一台服务器上执行的最大重试次数
    final int maxRetrysSame = retryHandler.getMaxRetriesOnSameServer();
    //要重试的最大不同服务器数
    final int maxRetrysNext = retryHandler.getMaxRetriesOnNextServer();
    // 使用负载均衡
    Observable<T> o = 
    //selectService()进行负载均衡
            (server == null ? selectServer() : Observable.just(server))
            .concatMap(new Func1<Server, Observable<T>>() {
                @Override
                // Called for each server being selected
                public Observable<T> call(Server server) {
                    context.setServer(server);
                    //获取ServerStats
                    final ServerStats stats = loadBalancerContext.getServerStats(server);
                    
                    // Called for each attempt and retry
                    Observable<T> o = Observable
                            .just(server)
                            .concatMap(new Func1<Server, Observable<T>>() {
                                @Override
                                public Observable<T> call(final Server server) {
                                    context.incAttemptCount();
                                    loadBalancerContext.noteOpenConnection(stats);
                                    
                                    if (listenerInvoker != null) {
                                        try {
                                            listenerInvoker.onStartWithServer(context.toExecutionInfo());
                                        } catch (AbortExecutionException e) {
                                            return Observable.error(e);
                                        }
                                    }
                                    //获取watch对象 就是一个Timer
                                    final Stopwatch tracer = loadBalancerContext.getExecuteTracer().start();
                                    //在此处执行 传进来的 方法 也就是executeWithLoadBalancer方法
                                    return operation.call(server).doOnEach(new Observer<T>() {
                                        private T entity;
                                        @Override
                                        public void onCompleted() {
                                            //完成请求 设置ServerStats 记录调用成功失败请求数以及最后请求失败时间
                                            recordStats(tracer, stats, entity, null);
                                        }

                                        @Override
                                        public void onError(Throwable e) {
                                              //完成请求 设置ServerStats 记录调用成功失败请求数以及最后请求失败时间
                                            recordStats(tracer, stats, null, e);
                                            //回调listenerInvoker
                                            if (listenerInvoker != null) {
                                                listenerInvoker.onExceptionWithServer(e, context.toExecutionInfo());
                                            }
                                        }
                                        @Override
                                        public void onNext(T entity) {
                                            this.entity = entity;
                                            if (listenerInvoker != null) {
                                                listenerInvoker.onExecutionSuccess(entity, context.toExecutionInfo());
                                            }
                                        }                                                                    
                                        private void recordStats(Stopwatch tracer, ServerStats stats, Object entity, Throwable exception) {
                                            //watch关闭啊
                                            tracer.stop();
                                            //记录请求成功失败数 以及最后一次请求失败时间
                                            loadBalancerContext.noteRequestCompletion(stats, entity, exception, tracer.getDuration(TimeUnit.MILLISECONDS), retryHandler);
                                        }
                                    });
                                }
                            });
                   
                    if (maxRetrysSame > 0) 
                        o = o.retry(retryPolicy(maxRetrysSame, true));
                    return o;
                }
            });
     //如果重试次数>0进行重试机制
    if (maxRetrysNext > 0 && server == null) 
        o = o.retry(retryPolicy(maxRetrysNext, false));
        //当发生异常
    return o.onErrorResumeNext(new Func1<Throwable, Observable<T>>() {
        @Override
        public Observable<T> call(Throwable e) {
            if (context.getAttemptCount() > 0) {
                if (maxRetrysNext > 0 && context.getServerAttemptCount() == (maxRetrysNext + 1)) {
                    e = new ClientException(ClientException.ErrorType.NUMBEROF_RETRIES_NEXTSERVER_EXCEEDED,
                            "Number of retries on next server exceeded max " + maxRetrysNext
                            + " retries, while making a call for: " + context.getServer(), e);
                }
                else if (maxRetrysSame > 0 && context.getAttemptCount() == (maxRetrysSame + 1)) {
                    e = new ClientException(ClientException.ErrorType.NUMBEROF_RETRIES_EXEEDED,
                            "Number of retries exceeded max " + maxRetrysSame
                            + " retries, while making a call for: " + context.getServer(), e);
                }
            }
            if (listenerInvoker != null) {
                listenerInvoker.onExecutionFailed(e, context.toFinalExecutionInfo());
            }
            return Observable.error(e);
        }
    });


public T executeWithLoadBalancer(final S request, final IClientConfig requestConfig) throws ClientException {
    LoadBalancerCommand<T> command = buildLoadBalancerCommand(request, requestConfig);
    try {
        return command.submit(
            new ServerOperation<T>() {
                @Override
                public Observable<T> call(Server server) {
                    //调用前准备工作
                    URI finalUri = reconstructURIWithServer(server, request.getUri());
                    S requestForServer = (S) request.replaceUri(finalUri);
                    try {
                        //发起调用 最终会走到FeignLoadBalancer 没有设置重试的情况下
                        return Observable.just(AbstractLoadBalancerAwareClient.this.execute(requestForServer, requestConfig));
                    } 
                    catch (Exception e) {
                        return Observable.error(e);
                    }
                }
            })
            .toBlocking()
            .single();
    } catch (Exception e) {
        //对异常进行包装 抛出一个 clientException
        Throwable t = e.getCause();
        if (t instanceof ClientException) {
            throw (ClientException) t;
        } else {
            throw new ClientException(e);
        }
    }
}


//创建LoadBalancerCommand
   protected LoadBalancerCommand<T> buildLoadBalancerCommand(final S request, final IClientConfig config) {
       //创建请求重试处理器
   RequestSpecificRetryHandler handler = getRequestSpecificRetryHandler(request, config);
   //使用构造方法创建 
   LoadBalancerCommand.Builder<T> builder = LoadBalancerCommand.<T>builder()
   //上下文
         .withLoadBalancerContext(this)
         //重试处理器
         .withRetryHandler(handler)
         //请求uri 此时还有没获取ip uri仍然是 http:///path 格式
         .withLoadBalancerURI(request.getUri());
         //定制化的LoadBalancerCommand 提供扩展
   customizeLoadBalancerCommandBuilder(request, config, builder);
   return builder.build();
}

FeignLoadBalancer中exectue方法

@Override
public RibbonResponse execute(RibbonRequest request, IClientConfig configOverride)
      throws IOException {
          //进行配置替换 robbin配置覆盖feign配置
   Request.Options options;
   if (configOverride != null) {
      RibbonProperties override = RibbonProperties.from(configOverride);
      options = new Request.Options(override.connectTimeout(this.connectTimeout),
            override.readTimeout(this.readTimeout));
   }
   else {
      options = new Request.Options(this.connectTimeout, this.readTimeout);
   }
   //使用代理的 client 执行http调用 默认为Client中内部类 Default实现 使用的是jdk原生的http
   Response response = request.client().execute(request.toRequest(), options);
   return new RibbonResponse(request.getUri(), response);
}

负载均衡获取ip

LoadBalancerCommand中selectServer方法

private Observable<Server> selectServer() {
    return Observable.create(new OnSubscribe<Server>() {
        @Override
        public void call(Subscriber<? super Server> next) {
            try {
                //负载均衡获取server
                Server server = loadBalancerContext.getServerFromLoadBalancer(loadBalancerURI, loadBalancerKey);
                //设置server   
                next.onNext(server);
                //完成
                next.onCompleted();
            } catch (Exception e) {
                next.onError(e);
            }
        }
    });
}

LoadBalanceContext 中getServerFromLoadBalancer方法

public Server getServerFromLoadBalancer(@Nullable URI original, @Nullable Object loadBalancerKey) throws ClientException {
    String host = null;
    int port = -1;
    if (original != null) {
        //格式为 http:///path
        host = original.getHost();
    }
    if (original != null) {
        Pair<String, Integer> schemeAndPort = deriveSchemeAndPortFromPartialUri(original);        
        port = schemeAndPort.second();
    }
    //ZoneAwareLoadBalancer 默认实现 夫类为 DynamicServerListLoadBalancer和BaseLoadBalancer 
    ILoadBalancer lb = getLoadBalancer();
    if (host == null) {
        if (lb != null){
            //根据loadbalancerkey获取server 最终会走到BaseLoadBalancer 中
            Server svc = lb.chooseServer(loadBalancerKey);
            if (svc == null){
                throw new ClientException(ClientException.ErrorType.GENERAL,
                        "Load balancer does not have available server for client: "
                                + clientName);
            }
            //判断host不能为null
            host = svc.getHost();
            if (host == null){
                throw new ClientException(ClientException.ErrorType.GENERAL,
                        "Invalid Server for :" + svc);
            }
            return svc;
        } 
    return new Server(host, port);
}

BaseLoadBalancer 中chooseServer

public Server chooseServer(Object key) {
    if (counter == null) {
        counter = createCounter();
    }
    counter.increment();
    if (rule == null) {
        return null;
    } else {
        try {
           // PredicateBasedRule
            return rule.choose(key);
        } catch (Exception e) {
            logger.warn("LoadBalancer [{}]:  Error choosing server for key {}", name, key, e);
            return null;
        }
    }
}

PredicateBasedRule 中choose方法

@Override
public Server choose(Object key) {
    ILoadBalancer lb = getLoadBalancer();
    Optional<Server> server = getPredicate().chooseRoundRobinAfterFiltering(lb.getAllServers(), key);
    if (server.isPresent()) {
        return server.get();
    } else {
        return null;
    }       
}

AbstractServerPredicate中chooseRoundRobinAfterFiltering


public Optional<Server> chooseRoundRobinAfterFiltering(List<Server> servers, Object loadBalancerKey) {
    //获取所有满足条件的server列表
    List<Server> eligible = getEligibleServers(servers, loadBalancerKey);
    if (eligible.size() == 0) {
        return Optional.absent();
    }
    //使用incrementAndGetModulo方法获取单个
    return Optional.of(eligible.get(incrementAndGetModulo(eligible.size())));
}

//轮询算法获取
private int incrementAndGetModulo(int modulo) {
    for (;;) {
        int current = nextIndex.get();
        int next = (current + 1) % modulo;
        if (nextIndex.compareAndSet(current, next) && current < modulo)
            return current;
    }
}
  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值