HystrixFeign
Hystrix主要任务是熔断限流,Feign和Hystrix来进行整合可以实现高可用的业务场景。
public final class HystrixFeign {
public static Builder builder() {
return new Builder();
}
public static final class Builder extends Feign.Builder {
private Contract contract = new Contract.Default();
// 构建setterFactory
private SetterFactory setterFactory = new SetterFactory.Default();
// 构建setterFactory
public Builder setterFactory(SetterFactory setterFactory) {
this.setterFactory = setterFactory;
return this;
}
// 配置fallback
public <T> T target(Target<T> target, T fallback) {
// 判断fallback是否为空,不为空通过FallbackFactory构建一个fallbackFactory
return build(fallback != null ? new FallbackFactory.Default<T>(fallback) : null)
.newInstance(target);
}
// 配置fallbackFactory
public <T> T target(Target<T> target, FallbackFactory<? extends T> fallbackFactory) {
// 构建创建实例
return build(fallbackFactory).newInstance(target);
}
// 配置Target返回实例对象
public <T> T target(Class<T> apiType,
String url,
FallbackFactory<? extends T> fallbackFactory) {
return target(new Target.HardCodedTarget<T>(apiType, url), fallbackFactory);
}
@Override
public Feign.Builder invocationHandlerFactory(InvocationHandlerFactory invocationHandlerFactory) {
throw new UnsupportedOperationException();
}
@Override
public Builder contract(Contract contract) {
this.contract = contract;
return this;
}
@Override
public Feign build() {
return build(null);
}
/** Configures components needed for hystrix integration. */
Feign build(final FallbackFactory<?> nullableFallbackFactory) {
// 设置代理工厂
super.invocationHandlerFactory(new InvocationHandlerFactory() {
@Override
public InvocationHandler create(Target target,
Map<Method, MethodHandler> dispatch) {
// 使用Hystrix的代理工厂处理器
return new HystrixInvocationHandler(target, dispatch, setterFactory,
nullableFallbackFactory);
}
});
// 设置Contract
super.contract(new HystrixDelegatingContract(contract));
return super.build();
}
//…… 忽略默认的处理方法
}
}
相对于Feign的默认信息,HystrixFeign通过自己的HystrixInvocationHandler来实现了代理处理。
HystrixInvocationHandler
final class HystrixInvocationHandler implements InvocationHandler {
private final Target<?> target;
private final Map<Method, MethodHandler> dispatch;
private final FallbackFactory<?> fallbackFactory; // Nullable
private final Map<Method, Method> fallbackMethodMap;
private final Map<Method, Setter> setterMethodMap;
HystrixInvocationHandler(Target<?> target, Map<Method, MethodHandler> dispatch,
SetterFactory setterFactory, FallbackFactory<?> fallbackFactory) {
this.target = checkNotNull(target, "target");
this.dispatch = checkNotNull(dispatch, "dispatch");
this.fallbackFactory = fallbackFactory;
this.fallbackMethodMap = toFallbackMethod(dispatch);
this.setterMethodMap = toSetters(setterFactory, target, dispatch.keySet());
}
static Map<Method, Method> toFallbackMethod(Map<Method, MethodHandler> dispatch) {
Map<Method, Method> result = new LinkedHashMap<Method, Method>();
for (Method method : dispatch.keySet()) {
method.setAccessible(true);
result.put(method, method);
}
return result;
}
/**
* Process all methods in the target so that appropriate setters are created.
*/
static Map<Method, Setter> toSetters(SetterFactory setterFactory,
Target<?> target,
Set<Method> methods) {
Map<Method, Setter> result = new LinkedHashMap<Method, Setter>();
for (Method method : methods) {
method.setAccessible(true);
result.put(method, setterFactory.create(target, method));
}
return result;
}
@Override
public Object invoke(final Object proxy, final Method method, final Object[] args)
throws Throwable {
// early exit if the invoked method is from java.lang.Object
// code is the same as ReflectiveFeign.FeignInvocationHandler
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();
}
// 构建HystrixCommand
HystrixCommand<Object> hystrixCommand =
new HystrixCommand<Object>(setterMethodMap.get(method)) {
@Override
protected Object run() throws Exception {
try {
return HystrixInvocationHandler.this.dispatch.get(method).invoke(args);
} catch (Exception e) {
throw e;
} catch (Throwable t) {
throw (Error) t;
}
}
@Override
protected Object getFallback() {
if (fallbackFactory == null) {
// 如果fallbackFactory为空执行HystrixCommand默认fallback
return super.getFallback();
}
try {
// 构建fallback
Object fallback = fallbackFactory.create(getExecutionException());
// 代理执行fallback
Object result = fallbackMethodMap.get(method).invoke(fallback, args);
if (isReturnsHystrixCommand(method)) {
return ((HystrixCommand) result).execute();
} else if (isReturnsObservable(method)) {
// Create a cold Observable
return ((Observable) result).toBlocking().first();
} else if (isReturnsSingle(method)) {
// Create a cold Observable as a Single
return ((Single) result).toObservable().toBlocking().first();
} else if (isReturnsCompletable(method)) {
((Completable) result).await();
return null;
} else if (isReturnsCompletableFuture(method)) {
return ((Future) result).get();
} else {
return result;
}
} catch (IllegalAccessException e) {
// shouldn't happen as method is public due to being an interface
throw new AssertionError(e);
} catch (InvocationTargetException | ExecutionException e) {
// Exceptions on fallback are tossed by Hystrix
throw new AssertionError(e.getCause());
} catch (InterruptedException e) {
// Exceptions on fallback are tossed by Hystrix
Thread.currentThread().interrupt();
throw new AssertionError(e.getCause());
}
}
};
// 执行hystrixCommand
if (Util.isDefault(method)) {
return hystrixCommand.execute();
} else if (isReturnsHystrixCommand(method)) {
return hystrixCommand;
} else if (isReturnsObservable(method)) {
// Create a cold Observable
return hystrixCommand.toObservable();
} else if (isReturnsSingle(method)) {
// Create a cold Observable as a Single
return hystrixCommand.toObservable().toSingle();
} else if (isReturnsCompletable(method)) {
return hystrixCommand.toObservable().toCompletable();
} else if (isReturnsCompletableFuture(method)) {
return new ObservableCompletableFuture<>(hystrixCommand);
}
return hystrixCommand.execute();
}
private boolean isReturnsCompletable(Method method) {
return Completable.class.isAssignableFrom(method.getReturnType());
}
private boolean isReturnsHystrixCommand(Method method) {
return HystrixCommand.class.isAssignableFrom(method.getReturnType());
}
private boolean isReturnsObservable(Method method) {
return Observable.class.isAssignableFrom(method.getReturnType());
}
private boolean isReturnsCompletableFuture(Method method) {
return CompletableFuture.class.isAssignableFrom(method.getReturnType());
}
private boolean isReturnsSingle(Method method) {
return Single.class.isAssignableFrom(method.getReturnType());
}
//……忽略部分方法
}
最终的结果就是通过HystrixCommand来进行包装最终执行execute,调用feign的invoke方法。