Netflix Feign - Spring Cloud 整合 Feign 源码(八)

197 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。


LoadBalancerFeignClient的工作流程

SynchronousMethodHandler#invoke()

使用RequestTemplate.Factory buildTemplateFromArgs工厂根据argv构造RequestTemplate。

RequestTemplate template = buildTemplateFromArgs.create(argv);

使用RequestInterceptor遍历迭代RequestTemplate,通过Target接口应用RequestTemplate获取Request。

Request request = targetRequest(template);
Request targetRequest(RequestTemplate template) {
    for (RequestInterceptor interceptor : requestInterceptors) {
        interceptor.apply(template);
    }
    return target.apply(template);
}
public interface RequestInterceptor {

  /**
   * Called for every request. Add data using methods on the supplied {@link RequestTemplate}.
   */
  void apply(RequestTemplate template);
}
public interface Target<T> {

  /* The type of the interface this target applies to. ex. {@code Route53}. */
  Class<T> type();

  /* configuration key associated with this target. For example, {@code route53}. */
  String name();

  /* base HTTP URL of the target. For example, {@code https://api/v2}. */
  String url();

  /**
   * Targets a template to this target, adding the {@link #url() base url} and any target-specific
   * headers or query parameters. <br>
   * <br>
   * For example: <br>
   * 
   * <pre>
   * public Request apply(RequestTemplate input) {
   *   input.insert(0, url());
   *   input.replaceHeader(&quot;X-Auth&quot;, currentToken);
   *   return input.asRequest();
   * }
   * </pre>
   * 
   * <br>
   * <br>
   * <br>
   * <b>relationship to JAXRS 2.0</b><br>
   * <br>
   * This call is similar to {@code
   * javax.ws.rs.client.WebTarget.request()}, except that we expect transient, but necessary
   * decoration to be applied on invocation.
   */
  public Request apply(RequestTemplate input);
}

遍历请求拦截器,将每个请求拦截求都应用到RequestTemplate请求模板上面去,也就是让每个请求拦截器对请求进行处理。

target.apply(template):其实就是基于RequestTemplate,创建了一个Request出来,这个Request是基于HardCodedTarget(包含了目标请求服务信息的一个Target),处理RequestTemplate,生成一个Request

http://eureka-provider-ribbon-feign-api-impl,是包含在HardCodedTarget中的

Response response = client.execute(request, options)

LoadBalancerFeignClient,将请求的参数传进去,连接超时时间是10s,读超时时间是60s【Request、Options】

基于LoadBalancerFeignClient完成请求的处理和发送,将http请求发送到了对方的eureka-provider-ribbon-feign-api-impl的某个server,同时获取response响应。

uriWithoutHost:从请求url地址中,取出来了要访问的服务的名称【eureka-provider-ribbon-feign-api-impl】,然后将请求url中的服务名称给剔除掉

FeignLoadBalancer.RibbonRequest ribbonRequest:基于去除了服务名称的uri地址【uriWithoutHost】,创建一个基于Ribbon的RibbonRequest。

FeignLoadBalancer.RibbonRequest ribbonRequest = new FeignLoadBalancer.RibbonRequest(this.delegate, request, uriWithoutHost);

IClientConfig:ribbon相关的一些配置

根据服务名称,获取对应的FeignLoadBalancer。在FeignLoadBalancer里封装了ribbon的ILoadBalancer。

ILoadBalancer & BaseLoadBalancer & DynamicServerListLoadBalancer & ZoneAwareLoadBalancer

ServerList & DiscoveryEnabledNIWSServerList & DomainExtractingServerList