目录
3)代理执行this.handler.invoke(this, methods[0], arrayOfObject);
4)MockClusterInvoker.invoke(new RpcInvocation(method, args)).recreate();
5)容错集群执行 FailoverClusterInvoker.invoke 处理隐式传参,目录查找所有服务提供则,以及获取对应的负载均衡算法
6)容错集群执行 FailoverClusterInvoker.doInvoke 进行路由Router过滤,和负载均衡算法选出一个Invoker(服务提供者)
2)执行DubboInvoker.invoke->DubboInvoker.doInvoke 获取与服务提供者建立的连接客户端,随后将请求委派客户端发送
4:currentClient.request(inv, timeout).get() 请求进入信息交换层Exchange,封装Request
5:请求Request 进入Transport层,进行传输层数据发送 (NettyClient.send)
6:request 委托socket发送完毕后,返回DefaultFuture,调用其get方法,阻塞当前消费线程
服务消费过程
1:获取对应接口服务的代理类
如:proxy0 implements ClassGenerator.DC, EchoService, DemoService 见下文
2:委托接口代理类查找可执行的Invoker(服务提供者)
过程如:
1)调用接口方法
如:demoService.sayHello
2)proxy0.要执行的方法 //代理执行,
见图1
3)代理执行this.handler.invoke(this, methods[0], arrayOfObject);
//InvokerInvocationHandler.invoke 见图2
4)MockClusterInvoker.invoke(new RpcInvocation(method, args)).recreate();
//见图3
图1:
package com.alibaba.dubbo.common.bytecode;
import com.alibaba.dubbo.demo.DemoService;
import com.alibaba.dubbo.rpc.service.EchoService;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
//通过JavassistProxyFactory 为接口生成的代理类如下:
public class proxy0
implements ClassGenerator.DC, EchoService, DemoService
{
public static Method[] methods;
private InvocationHandler handler;
//为 InvokerInvocationHandler 包装了MockClusterInvoker(其具备集群容错,目录查找,路由功能的Invoker)
public String sayHello(String paramString)
{
Object[] arrayOfObject = new Object[1];
arrayOfObject[0] = paramString;
Object localObject = this.handler.invoke(this, methods[0], arrayOfObject);
return (String)localObject;
}
public Object $echo(Object paramObject)
{
Object[] arrayOfObject = new Object[1];
arrayOfObject[0] = paramObject;
Object localObject = this.handler.invoke(this, methods[1], arrayOfObject);
return (Object)localObject;
}
public proxy0() {}
public proxy0(InvocationHandler paramInvocationHandler)
{
this.handler = paramInvocationHandler;
}
}
所以无论是基于JDK还是Javassit 生成的消费接口的动态代理类,在进行方法调用的时候
都是直接执行到InvokerInvocationHandler 中的invoke方法,然后通过Invoker方法在执行MockClusterInvoker中的invoke方法
public class InvokerInvocationHandler implements InvocationHandler {
private final Invoker<?> invoker; //其具备集群容错,目录查找,路由功能的Invoker
public InvokerInvocationHandler(Invoker<?> handler) {
this.invoker = handler;
}
@Override
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(invoker, args);
}
if ("toString".equals(methodName) && parameterTypes.length == 0) {
return invoker.toString();
}
if ("hashCode".equals(methodName) && parameterTypes.length == 0) {
return invoker.hashCode();
}
if ("equals".equals(methodName) && parameterTypes.length == 1) {
return invoker.equals(args[0]);
}
return invoker.invoke(new RpcInvocation(method, args)).recreate();//接口代理类的方法执行,最后会执行到此处
//new RpcInvocation(method, args) 封装需要执行的接口类方法信息和方法参数,
//通过一系类的处理后,将方法调用信息和参数传递给服务提供者(后续具体过程讲解)。
}
}
图2:
图3:
5)容错集群执行 FailoverClusterInvoker.invoke 处理隐式传参,目录查找所有服务提供则,以及获取对应的负载均衡算法
public Result invoke(final Invocation invocation) throws RpcException {
checkWhetherDestroyed();
LoadBalance loadbalance = null;
// binding attachments into invocation.
Map<String, String> contextAttachments = RpcContext.getContext().getAttachments();//获取隐式传参
if (contextAttachments != null && contextAttachments.size() != 0) {
((RpcInvocation) invocation).addAttachments(context