前面消费者提到过代理对象是通过JavassistProxyFactory 动态生成的,所以当调用sayHelloService.sayHello(name);
时,实际上是调用proxy里面的返回的 InvokerInvocationHandler 包装过的,基于前面已经包装过的directory,
现在就是 InvokerInvocationHandler (MockClusterInvoker(FailoverClusterInvoker(directory)))
public class JavassistProxyFactory extends AbstractProxyFactory {
public JavassistProxyFactory() {
}
public <T> T getProxy(Invoker<T> invoker, Class<?>[] interfaces) {
return Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker));
}
public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) {
final Wrapper wrapper = Wrapper.getWrapper(proxy.getClass().getName().indexOf(36) < 0 ? proxy.getClass() : type);
return new AbstractProxyInvoker<T>(proxy, type, url) {
protected Object doInvoke(T proxy, String methodName, Class<?>[] parameterTypes, Object[] arguments) throws Throwable {
return wrapper.invokeMethod(proxy, methodName, parameterTypes, arguments);
}
};
}
}
所以入口类就是 InvokerInvocationHandler 在基于上面调调用链一层一层往下
public class InvokerInvocationHandler implements InvocationHandler {
private static final Logger logger = LoggerFactory.getLogger(InvokerInvocationHandler.class);
private final Invoker<?> invoker;
public InvokerInvocationHandler(Invoker<?> handler) {
this.invoker = handler;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String methodName = method.getName();
Class<?>[] parameterTypes = method.getParameterTypes();
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this.invoker, args);
} else if ("toString".equals(methodName) && parameterTypes.length == 0) {
return this.invoker.toString();
} else if ("hashCode".equals(methodName) && parameterTypes.length == 0) {
return this.invoker.hashCode();
} else {
return "equals".equals(methodName) && parameterTypes.length == 1 ? this.invoker.equals(args[0]) : this.invoker.invoke(new RpcInvocation(method, args)).recreate();
}
}
}
当调用service接口的时候就是在调用InvokerInvocationHandler的invoker方法,在invoker方法中会把方法名method和参数args包装成一个RocInvoker对象,此时在调用invoker.invoker就是进入了上面说的包装类中
this.invoker.invoke(new RpcInvocation(method, args)
进入MockClusterInvoker,这是一个降级
public Result invoke(Invocation invocation) throws RpcException {
Result result = null;
String value = this.directory.getUrl().getMethodParameter(invocation.getMethodName(), "mock", Boolean.FALSE.toString()).trim();
if (value.length() != 0 && !value.equalsIgnoreCase("false")) {
// 是否强制走降级,根据我们的配置
// 比如服务没准备好,返回测试数据让代码可以走通
if (value.startsWith("force")) {
if (logger.isWarnEnabled()) {
logger.warn("force-mock: " + invocation.getMethodName() + " force-mock enabled , url : " + this.directory.getUrl());
}
result = this.doMockInvoke(invocation, (RpcException)null);
} else {
// 远程调用
try {
result = this.invoker.invoke(invocation);
} catch (RpcException var5) {
// 判断是否是业务异常,是就直接抛出
if (var5.isBiz()) {
throw var5;
}
// 不是就走降级策略
if (logger.isWarnEnabled()) {
logger.warn("fail-mock: " + invocation.getMethodName() + " fail-mock enabled , url : " + this.directory.getUrl(), var5);
}
result = this.doMockInvoke(invocation, var5);
}
}
} else {
// 不走mock操作
// 远程调用
result = this.invoker.invoke(invocation);
}
return result;
}
没有配置mock所以不走mock操作,进入下一个 FailoverClusterInvoker
进入后发现没有invoker方法,老规矩看父类
public class FailoverClusterInvoker<T> extends AbstractClusterInvoker<T> {
private static final Logger logger = LoggerFactory.getLogger(FailoverClusterInvoker.class);
public FailoverClusterInvoker(Directory<T> directory) {
super(directory);
}
public Result doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException {
// tudo
}
}
进入 AbstractClusterInvoker
public Result invoke(Invocation invocation) throws RpcException {
this.checkWhetherDestroyed();
Map<String, String> contextAttachments = RpcContext.getContext().getAttachments();
if (contextAttachments != null && contextAttachments.size() != 0) {
((RpcInvocation)invocation).addAttachments(contextAttachments);
}
// 从directory拿到远程调用列表,里面还会有一个根据标签的route
List<Invoker<T>> invokers = this.list(invocation);
// 根据我们配置的loadbalance 拿到一个负载均衡策略,默认为random
// 然后选择invokers其中一个去调用
LoadBalance loadbalance = this.initLoadBalance(invokers, invocation);
RpcUtils.attachInvocationIdIfAsync(this.getUrl(), invocation);
return this.doInvoke(invocation, invokers, loadbalance);
}
// 默认返回RandomLoadBalance
protected LoadBalance initLoadBalance(List<Invoker<T>> invokers, Invocation invocation) {
return CollectionUtils.isNotEmpty(invokers) ? (LoadBalance)ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(((Invoker)invokers.get(0)).getUrl().getMethodParameter(RpcUtils.getMethodName(invocation), "loadbalance", "random")) : (LoadBalance)ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension("random");
}
直接进入doInvoke ,这里没有配置容错策略默认是走 FailoverClusterInvoker
public Result doInvoke(Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException {
List<Invoker<T>> copyInvokers = invokers;
this.checkInvokers(invokers, invocation);
String methodName = RpcUtils.getMethodName(invocation);
// 获得重试次数,默认2次,包换直接调用的一共3次
int len = this.getUrl().getMethodParameter(methodName, "retries", 2) + 1;
if (len <= 0) {
len = 1;
}
RpcException le = null;
// 这里保存调用过的invoker,下次重试会排除
List<Invoker<T>> invoked = new ArrayList(invokers.size());
Set<String> providers = new HashSet(len);
for(int i = 0; i < len; ++i) {
if (i > 0) {
this.checkWhetherDestroyed();
copyInvokers = this.list(invocation);
this.checkInvokers(copyInvokers, invocation);
}
// 负载均衡得到一个invoker
Invoker<T> invoker = this.select(loadbalance, invocation, copyInvokers, invoked);
invoked.add(invoker);
RpcContext.getContext().setInvokers(invoked);
try {
Result result = invoker.invoke(invocation);
if (le != null && logger.isWarnEnabled()) {
// 省略打印日志
}
Result var13 = result;
return var13;
} catch (RpcException var18) {
// 业务异常抛出
if (var18.isBiz()) {
throw var18;
}
le = var18;
} catch (Throwable var19) {
le = new RpcException(var19.getMessage(), var19);
} finally {
providers.add(invoker.getUrl().getAddress());
}
}
}
到了select又进入AbstractClusterInvoker 集合只有一个直接返回,否则进入loadbalance.select
protected Invoker<T> select(LoadBalance loadbalance, Invocation invocation, List<Invoker<T>> invokers, List<Invoker<T>> selected) throws RpcException {
if (CollectionUtils.isEmpty(invokers)) {
return null;
} else {
String methodName = invocation == null ? "" : invocation.getMethodName();
boolean sticky = ((Invoker)invokers.get(0)).getUrl().getMethodParameter(methodName, "sticky", false);
if (this.stickyInvoker != null && !invokers.contains(this.stickyInvoker)) {
this.stickyInvoker = null;
}
if (sticky && this.stickyInvoker != null && (selected == null || !selected.contains(this.stickyInvoker)) && this.availablecheck && this.stickyInvoker.isAvailable()) {
return this.stickyInvoker;
} else {
Invoker<T> invoker = this.doSelect(loadbalance, invocation, invokers, selected);
if (sticky) {
this.stickyInvoker = invoker;
}
return invoker;
}
}
}
private Invoker<T> reselect(LoadBalance loadbalance, Invocation invocation, List<Invoker<T>> invokers, List<Invoker<T>> selected, boolean availablecheck) throws RpcException {
List<Invoker<T>> reselectInvokers = new ArrayList(invokers.size() > 1 ? invokers.size() - 1 : invokers.size());
Iterator var7 = invokers.iterator();
while(true) {
Invoker invoker;
do {
do {
if (!var7.hasNext()) {
if (!reselectInvokers.isEmpty()) {
return loadbalance.select(reselectInvokers, this.getUrl(), invocation);
}
if (selected != null) {
var7 = selected.iterator();
while(var7.hasNext()) {
invoker = (Invoker)var7.next();
if (invoker.isAvailable() && !reselectInvokers.contains(invoker)) {
reselectInvokers.add(invoker);
}
}
}
if (!reselectInvokers.isEmpty()) {
return loadbalance.select(reselectInvokers, this.getUrl(), invocation);
}
return null;
}
invoker = (Invoker)var7.next();
} while(availablecheck && !invoker.isAvailable());
} while(selected != null && selected.contains(invoker));
reselectInvokers.add(invoker);
}
}
进入 AbstractLoadBalance 的select 在调子类 RandomLoadBalance doSelect
protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {
int length = invokers.size();
boolean sameWeight = true;
int[] weights = new int[length];
// 权重根据配置和启动时间计算
int firstWeight = this.getWeight((Invoker)invokers.get(0), invocation);
weights[0] = firstWeight;
int totalWeight = firstWeight;
int offset;
int i;
for(offset = 1; offset < length; ++offset) {
i = this.getWeight((Invoker)invokers.get(offset), invocation);
weights[offset] = i;
totalWeight += i;
if (sameWeight && i != firstWeight) {
sameWeight = false;
}
}
// 配置的服务权重不一样走这里
if (totalWeight > 0 && !sameWeight) {
offset = ThreadLocalRandom.current().nextInt(totalWeight);
for(i = 0; i < length; ++i) {
offset -= weights[i];
if (offset < 0) {
return (Invoker)invokers.get(i);
}
}
}
// 配置的服务权重一样随机返回一个
return (Invoker)invokers.get(ThreadLocalRandom.current().nextInt(length));
}
得到一个invoker后返回FailoverClusterInvoker
这里的invoker是之前包装好 InvokerDelegate(ProtocolFilterWrapper(ListenerInvokerWrapper(DubboInvoker)))
跳过过滤连,这里会先进入抽象父类的invoker然后调用doInvoker 直接进入DubboInvoker
public Result invoke(Invocation inv) throws RpcException {
if (this.destroyed.get()) {
this.logger.warn("Invoker for service " + this + " on consumer " + NetUtils.getLocalHost() + " is destroyed, , dubbo version is " + Version.getVersion() + ", this invoker should not be used any longer");
}
RpcInvocation invocation = (RpcInvocation)inv;
invocation.setInvoker(this);
if (CollectionUtils.isNotEmptyMap(this.attachment)) {
invocation.addAttachmentsIfAbsent(this.attachment);
}
Map<String, String> contextAttachments = RpcContext.getContext().getAttachments();
if (CollectionUtils.isNotEmptyMap(contextAttachments)) {
invocation.addAttachments(contextAttachments);
}
invocation.setInvokeMode(RpcUtils.getInvokeMode(this.url, invocation));
RpcUtils.attachInvocationIdIfAsync(this.getUrl(), invocation);
try {
// 这里调用子类的doInvoker ,也就是DubboInvoker
return this.doInvoke(invocation);
} catch (InvocationTargetException var6) {
Throwable te = var6.getTargetException();
if (te == null) {
return AsyncRpcResult.newDefaultAsyncResult((Object)null, var6, invocation);
} else {
if (te instanceof RpcException) {
((RpcException)te).setCode(3);
}
return AsyncRpcResult.newDefaultAsyncResult((Object)null, te, invocation);
}
} catch (RpcException var7) {
if (var7.isBiz()) {
return AsyncRpcResult.newDefaultAsyncResult((Object)null, var7, invocation);
} else {
throw var7;
}
} catch (Throwable var8) {
return AsyncRpcResult.newDefaultAsyncResult((Object)null, var8, invocation);
}
}
DubboInvoker
protected Result doInvoke(Invocation invocation) throws Throwable {
RpcInvocation inv = (RpcInvocation)invocation;
String methodName = RpcUtils.getMethodName(invocation);
inv.setAttachment("path", this.getUrl().getPath());
inv.setAttachment("version", this.version);
// 这里是之前构建的链接
ExchangeClient currentClient;
if (this.clients.length == 1) {
currentClient = this.clients[0];
} else {
currentClient = this.clients[this.index.getAndIncrement() % this.clients.length];
}
try {
boolean isOneway = RpcUtils.isOneway(this.getUrl(), invocation);
int timeout = this.getUrl().getMethodPositiveParameter(methodName, "timeout", 1000);
// 是否存在返回值
if (isOneway) {
boolean isSent = this.getUrl().getMethodParameter(methodName, "sent", false);
currentClient.send(inv, isSent);
return AsyncRpcResult.newDefaultAsyncResult(invocation);
} else {
// 存在走这里
// 采用异步通信
AsyncRpcResult asyncRpcResult = new AsyncRpcResult(inv);
// timeout超时时间
CompletableFuture<Object> responseFuture = currentClient.request(inv, timeout);
asyncRpcResult.subscribeTo(responseFuture);
FutureContext.getContext().setCompatibleFuture(responseFuture);
return asyncRpcResult;
}
} catch (TimeoutException var9) {
throw new RpcException(2, "Invoke remote method timeout. method: " + invocation.getMethodName() + ", provider: " + this.getUrl() + ", cause: " + var9.getMessage(), var9);
} catch (RemotingException var10) {
throw new RpcException(1, "Failed to invoke remote method: " + invocation.getMethodName() + ", provider: " + this.getUrl() + ", cause: " + var10.getMessage(), var10);
}
}