3.Feign代理目标方法执行流程

Feign调用目标方法总体分为两种方式:直接调用 vs 融合服务治理。

服务治理主要基于两个指标【接口超时、接口异常】保护目标服务,相较于直接调用,Feign主要是在调用目标方法之前增强方式来实现服务治理涉及的降级 & 熔断功能。增强功能主要体现在JDK动态代理核心类InvocationHandler中,默认情况下选择FeignInvocationHandler,服务治理则选择FeignCircuitBreakerInvocationHandler。


1.FeignInvocationHandler

public class ReflectiveFeign extends Feign {

  static class FeignInvocationHandler implements InvocationHandler {

      // 表示具体的某个Feign客户端
      private final Target target;
      // 当前Feign客户端中所有目标方法 vs 目标方法对应的MethodHandler之SynchronousMethodHandler
      private final Map<Method, MethodHandler> dispatch;

      @Override
      public Object invoke(Object proxy, Method method, Object[] args){
          ...
          // 通过请求中目标方法在集合属性dispatch中获取对应的SynchronousMethodHandler
          return dispatch.get(method).invoke(args);
      }
  }

  Object executeAndDecode(RequestTemplate template, Options options) throws Throwable {
      Request request = targetRequest(template);
      Response response;
      long start = System.nanoTime();
      // 利用对应的client 请求真正目标方法
      response = client.execute(request, options);
      // ensure the request is set. TODO: remove in Feign 12
      response = response.toBuilder().request(request).requestTemplate(template).build();
      long elapsedTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);
      CompletableFuture<Object> resultFuture = new CompletableFuture<>();
      asyncResponseHandler.handleResponse(resultFuture, metadata.configKey(), response,metadata.returnType(), elapsedTime);
      ...
  }

}

2.FeignCircuitBreakerInvocationHandler

class FeignCircuitBreakerInvocationHandler implements InvocationHandler {

    public Object invoke(final Object proxy, final Method method, final Object[] args){
        ...
        String circuitName = circuitBreakerNameResolver.resolveCircuitBreakerName(feignClientName, target, method);
        // Resilience4JCircuitBreaker
        CircuitBreaker circuitBreaker = circuitBreakerGroupEnabled ? factory.create(circuitName,feignClientName):factory.create(circuitName);
        Supplier<Object> supplier = asSupplier(method, args);
        if (this.nullableFallbackFactory != null) {// 降级方法作为lambda表达式向下传递
          Function<Throwable, Object> fallbackFunction = throwable -> {
            Object fallback = this.nullableFallbackFactory.create(throwable);
            try {
              // 降级回调callback
              return this.fallbackMethodMap.get(method).invoke(fallback, args);
            }
            catch (Exception exception) {
              unwrapAndRethrow(exception);
            }
            return null;
          };
          return circuitBreaker.run(supplier, fallbackFunction);
        }
        return circuitBreaker.run(supplier);
  }

  private Supplier<Object> asSupplier(final Method method, final Object[] args) {
      RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
      Thread caller = Thread.currentThread();
      return () -> {// 初始化Supplier 跟 调用Supplier可能是不同线程
        // 判断是否为异步请求
        boolean isAsync = caller != Thread.currentThread();
        try {
          if (isAsync) {
            // 如果是异步请求,则将requestAttributes继续向当前请求往下传递
            RequestContextHolder.setRequestAttributes(requestAttributes);
          }
          // 承接默认InvocationHandler执行逻辑
          return dispatch.get(method).invoke(args);
        }finally {
          if (isAsync) {
            RequestContextHolder.resetRequestAttributes();
          }
        }
      };
    }

}

SpringCloud之Resilience4j熔断器源码解析