Feign调用目标方法总体分为两种方式:直接调用 vs 融合服务治理。
服务治理主要基于两个指标【接口超时、接口异常】保护目标服务,相较于直接调用,Feign主要是在调用目标方法之前增强方式来实现服务治理涉及的降级 & 熔断功能。增强功能主要体现在JDK动态代理核心类InvocationHandler中,默认情况下选择FeignInvocationHandler,服务治理则选择FeignCircuitBreakerInvocationHandler。
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
限时策略、熔断策略是在类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
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。
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);
}
}
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;
}
};
}
}
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);
}
}
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。表示出现异常之后是否中断当前请求的线程。