Feign调用逻辑 未开启hystris
ReflectiveFeign静态内部类实现了InvocationHandler接口 当调用feign接口时候 会进入invoke方法
public class ReflectiveFeign{
static class FeignInvocationHandler implements InvocationHandler {
//代理的目标类HardCodedTarget
private final Target target;
//方法以及 方法的处理器 处理器实现类为 SynchronousMethodHandler
private final Map<Method, MethodHandler> dispatch;
FeignInvocationHandler(Target target, Map<Method, MethodHandler> dispatch) {
this.target = checkNotNull(target, "target");
this.dispatch = checkNotNull(dispatch, "dispatch for %s", target);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//对obeject中的方法进行判断和返回
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();
}
//从dispatch的map中获取method,调用method中的invoke方法 (SynchronousMethodHandler类中的invoke方法)
return dispatch.get(method).invoke(args);
}
}
}
SynchronousMethodHandler invoke方法
@Override
public Object invoke(Object[] argv) throws Throwable {
//将参数中的args 填充到之前解析的模版中
RequestTemplate template = buildTemplateFromArgs.create(argv);
//发现参数中 options类型
Options options = findOptions(argv);
//retryer copy创建
Retryer retryer = this.retryer.clone();
while (true) {
try {
//执行http请求 解码数据 返回
return executeAndDecode(template, options);
} catch (RetryableException e) {
try {
retryer.continueOrPropagate(e);
} catch (RetryableException th) {
Throwable cause = th.getCause();
if (propagationPolicy == UNWRAP && cause != null) {
throw cause;
} else {
throw th;
}
}
if (logLevel != Logger.Level.NONE) {
logger.logRetry(metadata.configKey(), logLevel);
}
continue;
}
}
}
SynchronousMethodHandler executeAndDecode方法
Object executeAndDecode(RequestTemplate template, Options options) throws Throwable {
//添加RequestInterceptor请求拦截器
Request request = targetRequest(template);
Response response;
//设置请求开始时间
long start = System.nanoTime();
try {
//执行调用获取 resonpse 调用LoadBalancerFeignClient的execute方法
response = client.execute(request, options);
} catch (IOException e) {
//出现io异常直接抛出
throw errorExecuting(request, e);
}
//记录请求响应的时间
long elapsedTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);
//是否应该关闭响应体 默认为true
boolean shouldClose = true;
try {
//先判断response类型 如何和之前解析出来的类型一直 直接返回
if (Response.class == metadata.returnType()) {
if (response.body() == null) {
return response;
}
if (response.body().length() == null ||
response.body().length() > MAX_RESPONSE_BUFFER_SIZE) {
//如果返回的body的长度 >8192L 响应体直接返回
shouldClose = false;
return response;
}
// 响应体没有断开 直接解析成 byte数组返回
byte[] bodyData = Util.toByteArray(response.body().asInputStream());
return response.toBuilder().body(bodyData).build();
}
//如果返回值和之前解析到的不一致 成功请求处理
if (response.status() >= 200 && response.status() < 300) {
//http请求为成功
if (void.class == metadata.returnType()) {
//返回值类型为void 直接返回null
return null;
} else {
//对返回提body进行解码处理,
Object result = decode(response);
//构建feign时为默认值 true
shouldClose = closeAfterDecode;
return result;
}
}
//404请求处理decode404 为true
else if (decode404 && response.status() == 404 && void.class != metadata.returnType()) {
Object result = decode(response);
shouldClose = closeAfterDecode;
return result;
}
//其他状态码直接 解析完抛出异常
else {
//抛出一个RetryableException 异常 外层方法捕获后处理
throw errorDecoder.decode(metadata.configKey(), response);
}
} catch (IOException e) {
throw errorReading(request, response, e);
} finally {
//关闭reponse响应体
if (shouldClose) {
ensureClosed(response.body());
}
}
}
LoadBalancerFeignClient中的 execute方法
@Override
public Response execute(Request request, Request.Options options) throws IOException {
try {
//进行url转换 String类型转换成URI类型
URI asUri = URI.create(request.url());
//获取服务名称 也就是feign注解配置的name
String clientName = asUri.getHost();
//将uri中的host清除掉 变成 http:///path 这种格式
URI uriWithoutHost = cleanUrl(request.url(), clientName);
//创建RibbonRequest请求对象 主要有3个参数 http代理类 默认为java的http调用,uri参数,以及feign.request读喜庆
FeignLoadBalancer.RibbonRequest ribbonRequest = new FeignLoadBalancer.RibbonRequest(
this.delegate, request, uriWithoutHost);
//获取Options 配置
IClientConfig requestConfig = getClientConfig(options, clientName);
//lbClient(clientName)
return lbClient(clientName)
.executeWithLoadBalancer(ribbonRequest, requestConfig).toResponse();
}
catch (ClientException e) {
IOException io = findIOException(e);
if (io != null) {
throw io;
}
throw new RuntimeException(e);
}
}
CachingSpringLoadBalancerFactory 中create方法(在 FeignRibbonClientAutoConfiguration自动装配类中 自动注入)
//获取负载均衡feignloadBalancer
public FeignLoadBalancer create(String clientName) {
//从缓存中获取 缓存类型为ConcurrentReferenceHashMap
FeignLoadBalancer client = this.cache.get(clientName);
if (client != null) {
return client;
}
//没有获取到缓存类型直接从SpringClientFactory中获取
// 最终走到NamedContextFactory 中获取如果存在直接返回 不存在反射创建
IClientConfig config = this.factory.getClientConfig(clientName);
ILoadBalancer lb = this.factory.getLoadBalancer(clientName);
//获取端口
ServerIntrospector serverIntrospector = this.factory.getInstance(clientName,
ServerIntrospector.class);
//创建client放入缓存中
client = this.loadBalancedRetryFactory != null
? new RetryableFeignLoadBalancer(lb, config, serverIntrospector,
this.loadBalancedRetryFactory)
: new FeignLoadBalancer(lb, config, serverIntrospector);
this.cache.put(clientName, client);
return client;
}
AbstractLoadBalancerAwareClient 中submit方法 和executeWithLoadBalancer 方法(参数传递方式)
public Observable<T> submit(final ServerOperation<T> operation) {
//请求上下文对象 里面包含server 服务调用量 以及服务调用总量?
final ExecutionInfoContext context = new ExecutionInfoContext();
//一般情况为null
if (listenerInvoker != null) {
try {
listenerInvoker.onExecutionStart();
} catch (AbortExecutionException e) {
return Observable.error(e);
}
}
//在一台服务器上执行的最大重试次数
final int maxRetrysSame = retryHandler.getMaxRetriesOnSameServer();
//要重试的最大不同服务器数
final int maxRetrysNext = retryHandler.getMaxRetriesOnNextServer();
// 使用负载均衡
Observable<T> o =
//selectService()进行负载均衡
(server == null ? selectServer() : Observable.just(server))
.concatMap(new Func1<Server, Observable<T>>() {
@Override
// Called for each server being selected
public Observable<T> call(Server server) {
context.setServer(server);
//获取ServerStats
final ServerStats stats = loadBalancerContext.getServerStats(server);
// Called for each attempt and retry
Observable<T> o = Observable
.just(server)
.concatMap(new Func1<Server, Observable<T>>() {
@Override
public Observable<T> call(final Server server) {
context.incAttemptCount();
loadBalancerContext.noteOpenConnection(stats);
if (listenerInvoker != null) {
try {
listenerInvoker.onStartWithServer(context.toExecutionInfo());
} catch (AbortExecutionException e) {
return Observable.error(e);
}
}
//获取watch对象 就是一个Timer
final Stopwatch tracer = loadBalancerContext.getExecuteTracer().start();
//在此处执行 传进来的 方法 也就是executeWithLoadBalancer方法
return operation.call(server).doOnEach(new Observer<T>() {
private T entity;
@Override
public void onCompleted() {
//完成请求 设置ServerStats 记录调用成功失败请求数以及最后请求失败时间
recordStats(tracer, stats, entity, null);
}
@Override
public void onError(Throwable e) {
//完成请求 设置ServerStats 记录调用成功失败请求数以及最后请求失败时间
recordStats(tracer, stats, null, e);
//回调listenerInvoker
if (listenerInvoker != null) {
listenerInvoker.onExceptionWithServer(e, context.toExecutionInfo());
}
}
@Override
public void onNext(T entity) {
this.entity = entity;
if (listenerInvoker != null) {
listenerInvoker.onExecutionSuccess(entity, context.toExecutionInfo());
}
}
private void recordStats(Stopwatch tracer, ServerStats stats, Object entity, Throwable exception) {
//watch关闭啊
tracer.stop();
//记录请求成功失败数 以及最后一次请求失败时间
loadBalancerContext.noteRequestCompletion(stats, entity, exception, tracer.getDuration(TimeUnit.MILLISECONDS), retryHandler);
}
});
}
});
if (maxRetrysSame > 0)
o = o.retry(retryPolicy(maxRetrysSame, true));
return o;
}
});
//如果重试次数>0进行重试机制
if (maxRetrysNext > 0 && server == null)
o = o.retry(retryPolicy(maxRetrysNext, false));
//当发生异常
return o.onErrorResumeNext(new Func1<Throwable, Observable<T>>() {
@Override
public Observable<T> call(Throwable e) {
if (context.getAttemptCount() > 0) {
if (maxRetrysNext > 0 && context.getServerAttemptCount() == (maxRetrysNext + 1)) {
e = new ClientException(ClientException.ErrorType.NUMBEROF_RETRIES_NEXTSERVER_EXCEEDED,
"Number of retries on next server exceeded max " + maxRetrysNext
+ " retries, while making a call for: " + context.getServer(), e);
}
else if (maxRetrysSame > 0 && context.getAttemptCount() == (maxRetrysSame + 1)) {
e = new ClientException(ClientException.ErrorType.NUMBEROF_RETRIES_EXEEDED,
"Number of retries exceeded max " + maxRetrysSame
+ " retries, while making a call for: " + context.getServer(), e);
}
}
if (listenerInvoker != null) {
listenerInvoker.onExecutionFailed(e, context.toFinalExecutionInfo());
}
return Observable.error(e);
}
});
public T executeWithLoadBalancer(final S request, final IClientConfig requestConfig) throws ClientException {
LoadBalancerCommand<T> command = buildLoadBalancerCommand(request, requestConfig);
try {
return command.submit(
new ServerOperation<T>() {
@Override
public Observable<T> call(Server server) {
//调用前准备工作
URI finalUri = reconstructURIWithServer(server, request.getUri());
S requestForServer = (S) request.replaceUri(finalUri);
try {
//发起调用 最终会走到FeignLoadBalancer 没有设置重试的情况下
return Observable.just(AbstractLoadBalancerAwareClient.this.execute(requestForServer, requestConfig));
}
catch (Exception e) {
return Observable.error(e);
}
}
})
.toBlocking()
.single();
} catch (Exception e) {
//对异常进行包装 抛出一个 clientException
Throwable t = e.getCause();
if (t instanceof ClientException) {
throw (ClientException) t;
} else {
throw new ClientException(e);
}
}
}
//创建LoadBalancerCommand
protected LoadBalancerCommand<T> buildLoadBalancerCommand(final S request, final IClientConfig config) {
//创建请求重试处理器
RequestSpecificRetryHandler handler = getRequestSpecificRetryHandler(request, config);
//使用构造方法创建
LoadBalancerCommand.Builder<T> builder = LoadBalancerCommand.<T>builder()
//上下文
.withLoadBalancerContext(this)
//重试处理器
.withRetryHandler(handler)
//请求uri 此时还有没获取ip uri仍然是 http:///path 格式
.withLoadBalancerURI(request.getUri());
//定制化的LoadBalancerCommand 提供扩展
customizeLoadBalancerCommandBuilder(request, config, builder);
return builder.build();
}
FeignLoadBalancer中exectue方法
@Override
public RibbonResponse execute(RibbonRequest request, IClientConfig configOverride)
throws IOException {
//进行配置替换 robbin配置覆盖feign配置
Request.Options options;
if (configOverride != null) {
RibbonProperties override = RibbonProperties.from(configOverride);
options = new Request.Options(override.connectTimeout(this.connectTimeout),
override.readTimeout(this.readTimeout));
}
else {
options = new Request.Options(this.connectTimeout, this.readTimeout);
}
//使用代理的 client 执行http调用 默认为Client中内部类 Default实现 使用的是jdk原生的http
Response response = request.client().execute(request.toRequest(), options);
return new RibbonResponse(request.getUri(), response);
}
负载均衡获取ip
LoadBalancerCommand中selectServer方法
private Observable<Server> selectServer() {
return Observable.create(new OnSubscribe<Server>() {
@Override
public void call(Subscriber<? super Server> next) {
try {
//负载均衡获取server
Server server = loadBalancerContext.getServerFromLoadBalancer(loadBalancerURI, loadBalancerKey);
//设置server
next.onNext(server);
//完成
next.onCompleted();
} catch (Exception e) {
next.onError(e);
}
}
});
}
LoadBalanceContext 中getServerFromLoadBalancer方法
public Server getServerFromLoadBalancer(@Nullable URI original, @Nullable Object loadBalancerKey) throws ClientException {
String host = null;
int port = -1;
if (original != null) {
//格式为 http:///path
host = original.getHost();
}
if (original != null) {
Pair<String, Integer> schemeAndPort = deriveSchemeAndPortFromPartialUri(original);
port = schemeAndPort.second();
}
//ZoneAwareLoadBalancer 默认实现 夫类为 DynamicServerListLoadBalancer和BaseLoadBalancer
ILoadBalancer lb = getLoadBalancer();
if (host == null) {
if (lb != null){
//根据loadbalancerkey获取server 最终会走到BaseLoadBalancer 中
Server svc = lb.chooseServer(loadBalancerKey);
if (svc == null){
throw new ClientException(ClientException.ErrorType.GENERAL,
"Load balancer does not have available server for client: "
+ clientName);
}
//判断host不能为null
host = svc.getHost();
if (host == null){
throw new ClientException(ClientException.ErrorType.GENERAL,
"Invalid Server for :" + svc);
}
return svc;
}
return new Server(host, port);
}
BaseLoadBalancer 中chooseServer
public Server chooseServer(Object key) {
if (counter == null) {
counter = createCounter();
}
counter.increment();
if (rule == null) {
return null;
} else {
try {
// PredicateBasedRule
return rule.choose(key);
} catch (Exception e) {
logger.warn("LoadBalancer [{}]: Error choosing server for key {}", name, key, e);
return null;
}
}
}
PredicateBasedRule 中choose方法
@Override
public Server choose(Object key) {
ILoadBalancer lb = getLoadBalancer();
Optional<Server> server = getPredicate().chooseRoundRobinAfterFiltering(lb.getAllServers(), key);
if (server.isPresent()) {
return server.get();
} else {
return null;
}
}
AbstractServerPredicate中chooseRoundRobinAfterFiltering
public Optional<Server> chooseRoundRobinAfterFiltering(List<Server> servers, Object loadBalancerKey) {
//获取所有满足条件的server列表
List<Server> eligible = getEligibleServers(servers, loadBalancerKey);
if (eligible.size() == 0) {
return Optional.absent();
}
//使用incrementAndGetModulo方法获取单个
return Optional.of(eligible.get(incrementAndGetModulo(eligible.size())));
}
//轮询算法获取
private int incrementAndGetModulo(int modulo) {
for (;;) {
int current = nextIndex.get();
int next = (current + 1) % modulo;
if (nextIndex.compareAndSet(current, next) && current < modulo)
return current;
}
}