Dubbo源码阅读之 客户端远程调用

【 DubboProtocolTest.java ====>> 客户端 ====>> DemoService.class的代理类 】
1. 构造函数:ccp.addConstructor(Modifier.PUBLIC, new Class<?>[]{ InvocationHandler.class }, new Class<?>[0], "handler=$1;");
2. 初始化:
public Object newInstance(java.lang.reflect.InvocationHandler h){ 
return new com.alibaba.dubbo.common.bytecode.proxy0($1); 
}
3. 方法 sayHello
public void sayHello(java.lang.String arg0){
Object[] args = new Object[1]; 
args[0] = ($w)$1; 
Object ret = handler.invoke(this, methods[12], args);
}


【 DubboProtocolTest.java ====>> 客户端 ====>> DubboInvoker.java 】
1. 字段
private final ExchangeClient[]      clients;
private final Set<Invoker<?>> invokers;
private final Class<T>   type;
private final URL        url;
2. 方法
Class<T> getInterface();
                        ======>>> 获取接口。
    Result invoke(Invocation invocation) throws RpcException;
                        ======>>> 调用目标方法。




【 DubboProtocolTest.java ====>> 客户端 ====>> RpcInvocation.java 】
1. 字段
private String               methodName;
    private Class<?>[]           parameterTypes;
    private Object[]             arguments;
    private Map<String, String>  attachments;
    private transient Invoker<?> invoker;


2. 方法
String getMethodName();
Class<?>[] getParameterTypes();
Object[] getArguments();
Map<String, String> getAttachments();
String getAttachment(String key);
String getAttachment(String key, String defaultValue);
    Invoker<?> getInvoker();


【 DubboProtocolTest.java ====>> RPC ====>> 远程调用 】
1. 初始化 RpcInvocation
                        ======>>> 方法名称,方法参数。
2. 初始化 Request
                        ======>>> Request req = new Request();
                        ======>>> req.setVersion("2.0.0");
                        ======>>> req.setTwoWay(true);
                        ======>>> req.setData(request);
3. NettyClient 中直接发送出去。
4. NettyServer 接收到消息,
5. 判断消息是否是Request,if (message instanceof Request){}
6. 判断是否是Event,if (request.isEvent())
7. 是否是TwoWay,if (request.isTwoWay())
8. 判断请求对象是否是坏的,if (req.isBroken())
9. 根据key来寻找目标DubboExporter,key的生成方式:key = 组名 + 服务名 + 服务版本 + 端口
    public static String serviceKey(int port, String serviceName, String serviceVersion, String serviceGroup) {
        StringBuilder buf = new StringBuilder();
        if (serviceGroup != null && serviceGroup.length() > 0) {
            buf.append(serviceGroup);
            buf.append("/");
        }
        buf.append(serviceName);
        if (serviceVersion != null && serviceVersion.length() > 0 && !"0.0.0".equals(serviceVersion)) {
            buf.append(":");
            buf.append(serviceVersion);
        }
        buf.append(":");
        buf.append(port);
        return buf.toString();
    }
10. 调用目标方法,返回结果,invoker.invoke(inv);
11. 封装响应对象,如果调用成功,响应对象为Response res = new Response(req.getId(), req.getVersion());res.setStatus(Response.OK);res.setResult(result);
12. 返回响应对象,发送给NettyClient,channel.send(response);
13. NettyClient接收到响应消息,根绝请求ID,回去Future,DefaultFuture future = FUTURES.remove(response.getId());
14. 往future中写数据,
private void doReceived(Response res) {
        lock.lock();
        try {
            response = res;
            if (done != null) {
                done.signal();
            }
        } finally {
            lock.unlock();
        }
        if (callback != null) {
            invokeCallback(callback);
        }
    }
15,主线程获取dubbo调用返回结果,
public Object get(int timeout) throws RemotingException {
        if (timeout <= 0) {
            timeout = Constants.DEFAULT_TIMEOUT;
        }
        if (! isDone()) {
            long start = System.currentTimeMillis();
            lock.lock();
            try {
                while (! isDone()) {
                    done.await(timeout, TimeUnit.MILLISECONDS);
                    if (isDone() || System.currentTimeMillis() - start > timeout) {
                        break;
                    }
                }
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } finally {
                lock.unlock();
            }
            if (! isDone()) {
                throw new TimeoutException(sent > 0, channel, getTimeoutMessage(false));
            }
        }
        return returnFromResponse();
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值