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

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

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

3.Feign代理目标方法执行流程_第1张图片


1.FeignInvocationHandler

public class ReflectiveFeign extends Feign {

  static class FeignInvocationHandler implements InvocationHandler {

      // 表示具体的某个Feign客户端
      private final Target target;
      // 当前Feign客户端中所有目标方法 vs 目标方法对应的MethodHandler之SynchronousMethodHandler
      private final Map 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 resultFuture = new CompletableFuture<>();
      asyncResponseHandler.handleResponse(resultFuture, metadata.configKey(), response,metadata.returnType(), elapsedTime);
      ...
  }

}

2.FeignCircuitBreakerInvocationHandler

限时策略、熔断策略是在类TraceFeignBlockingLoadBalancerClient核心逻辑【负载均衡、目标方法执行】之前触发的。

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 supplier = asSupplier(method, args);
        if (this.nullableFallbackFactory != null) {// 降级方法作为lambda表达式向下传递
          Function 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 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();
          }
        }
      };
    }

}
public class Resilience4JCircuitBreaker implements CircuitBreaker {
	// 熔断器相关配置类
	private final io.github.resilience4j.circuitbreaker.CircuitBreakerConfig circuitBreakerConfig;
	// InMemoryCircuitBreakerRegistry:熔断器注册表
	private final CircuitBreakerRegistry registry;
	// InMemoryTimeLimiterRegistry:限时器注册表
	private final TimeLimiterRegistry timeLimiterRegistry;
	// 限时器相关配置类
	private final TimeLimiterConfig timeLimiterConfig;
	private final ExecutorService executorService;
	
	public  T run(Supplier toRun, Function fallback) {
		io.vavr.collection.Map tags = io.vavr.collection.HashMap.of("group",this.groupName);
		//ID:标识某个Feign客户端中某个方法。熔断器注册表注册当前ID信息
		CircuitBreaker defaultCircuitBreaker = registry.circuitBreaker(this.id,this.circuitBreakerConfig, tags);
		circuitBreakerCustomizer.ifPresent(customizer -> customizer.customize(defaultCircuitBreaker));
		// 限时器注册表注册当前ID信息
		TimeLimiter timeLimiter = timeLimiterRegistry.timeLimiter(id, timeLimiterConfig, tags);
		if (bulkheadProvider != null) {
			return bulkheadProvider.run(this.groupName, toRun, fallback, defaultCircuitBreaker, timeLimiter, tags);
		}else {
			if (executorService != null) {//默认异步方式
				// 异步触发Ribbon调用下游服务
				Supplier> futureSupplier = () -> executorService.submit(toRun::get);
				//限时器策略
				Callable restrictedCall = TimeLimiter.decorateFutureSupplier(timeLimiter, futureSupplier);
				// 熔断器策略
				Callable callable = CircuitBreaker.decorateCallable(defaultCircuitBreaker, restrictedCall);
				return Try.of(callable::call)// 第一步:触发decorateCallable的Lambda表达式执行
							  .recover(fallback).get();// 第一步中存在异常则在recover内部回调fallback执行降级逻辑
			}else {Supplier decorator = CircuitBreaker.decorateSupplier(defaultCircuitBreaker, toRun);
				return Try.of(decorator::get).recover(fallback).get();
			}
		}
	}
}

try.of(触发熔断器策略执行).recover(如果熔断器执行过程中抛出异常则执行fallback).get(返回目标方法返回值)。       

熔断器内部:首先根据熔断器状态判断是否需要通过抛出异常来终止调用限时器策略,其次触发限时器策略执行,最后根据限时器执行结果选择正常返回还是执行fallback。

2.1.熔断器CircuitBreaker

2.1.1.熔断器表的注册

public final class InMemoryCircuitBreakerRegistry extends AbstractRegistry implements CircuitBreakerRegistry {
		public CircuitBreaker circuitBreaker(String name, CircuitBreakerConfig config,
		    io.vavr.collection.Map tags) {
		    return computeIfAbsent(name, () -> CircuitBreaker.of(name, config, getAllTags(tags)));
		}
}

name表示当前Feign客户端对应的某个方法,并且与CircuitBreakerStateMachine是一一对应关系。

CircuitBreakerStateMachine内部维护了当前name对应的熔断状态。

public interface CircuitBreaker {
		static CircuitBreaker of(String name, CircuitBreakerConfig circuitBreakerConfig,
		    io.vavr.collection.Map tags) {
		    return new CircuitBreakerStateMachine(name, circuitBreakerConfig, tags);
		}
}

2.1.2.熔断器策略执行

public interface CircuitBreaker {
    static  Callable decorateCallable(CircuitBreaker circuitBreaker, Callable callable) {
        return () -> {
            //熔断器初始值状态为关闭状态,该状态下acquirePermission不会有任何操作
            circuitBreaker.acquirePermission();
            final long start = circuitBreaker.getCurrentTimestamp();
            try {
                // 触发限时器
                T result = callable.call();
                long duration = circuitBreaker.getCurrentTimestamp() - start;//下游服务响应花费的时间
                circuitBreaker.onResult(duration, circuitBreaker.getTimestampUnit(), result);
                return result;
            } catch (Exception exception) {
                // Do not handle java.lang.Error
                long duration = circuitBreaker.getCurrentTimestamp() - start;
                circuitBreaker.onError(duration, circuitBreaker.getTimestampUnit(), exception);
                throw exception;
            }
        };
    }
}

2.2.限时器TimeLimiter

2.2.1.限时器表的注册

public class InMemoryTimeLimiterRegistry extends AbstractRegistry implements TimeLimiterRegistry {
		@Override
		public TimeLimiter timeLimiter(String name,TimeLimiterConfig timeLimiterConfig,
		    							io.vavr.collection.Map tags) {
		    return computeIfAbsent(name, () -> TimeLimiter.of(name,timeLimiterConfig), getAllTags(tags)));
		}
}
public interface TimeLimiter {
		static TimeLimiter of(String name, TimeLimiterConfig timeLimiterConfig,
		    io.vavr.collection.Map tags) {
		    return new TimeLimiterImpl(name, timeLimiterConfig, tags);
		}
}

2.2.2.限时器策略的执行

public class TimeLimiterImpl implements TimeLimiter {

    private final TimeLimiterConfig timeLimiterConfig;

    public > Callable decorateFutureSupplier(Supplier futureSupplier) {
        return () -> {
            Future future = futureSupplier.get();//由限时器触发executorService异步submit
            try {
                // resilience4j.timelimiter.configs.default.timeoutDuration:默认为1秒。
                // 从timeLimiterConfig获取限时时间,如果在限时时间内没有得到下游服务的响应,则降级处理
                T result = future.get(getTimeLimiterConfig().getTimeoutDuration().toMillis(),TimeUnit.MILLISECONDS);
                onSuccess();
                return result;//返回目标方法返回值
            } catch (TimeoutException e) {//限时时间内没有得到下游服务的响应,则降级处理
                TimeoutException timeoutException = TimeLimiter.createdTimeoutExceptionWithName(name, e);
                onError(timeoutException);
                ...
                throw timeoutException;
            } catch (ExecutionException e) {//限时时间内没有得到下游服务的响应,则降级处理
                Throwable t = e.getCause();
                if (t == null) {
                    onError(e);
                    throw e;
                }
                onError(t);
                if (t instanceof Error) {
                    throw (Error) t;
                }
                throw (Exception) t;
            }
        };
    }

}

resilience4j.timelimiter.configs.default.cancelRunningFuture:默认为true。表示出现异常之后是否中断当前请求的线程。

你可能感兴趣的:(java,开发语言)