dubbo dovoke源码解析

该代码段展示了Dubbo服务调用的核心逻辑,包括异步和同步调用的处理。在异步调用中,区分了是否需要返回值的情况。同步调用则通过客户端请求并等待响应。超时和网络异常作为可能的错误处理被捕捉并转化为RpcException。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

@Override
protected Result doInvoke(final Invocation invocation) throws Throwable {
RpcInvocation inv = (RpcInvocation) invocation;
final String methodName = RpcUtils.getMethodName(invocation);
inv.setAttachment(Constants.PATH_KEY, getUrl().getPath());
inv.setAttachment(Constants.VERSION_KEY, version);

    ExchangeClient currentClient;
    if (clients.length == 1) {
        currentClient = clients[0];
    } else {
        currentClient = clients[index.getAndIncrement() % clients.length];
    }
    try {
        boolean isAsync = RpcUtils.isAsync(getUrl(), invocation);
        boolean isOneway = RpcUtils.isOneway(getUrl(), invocation);
        int timeout = getUrl().getMethodParameter(methodName, Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT);
        //分支1: 如果是异步并且调用方直接表示不会调用其返回值
        // <dubbo : method name="findFoo" async="true" return="false"/>
        if (isOneway) {
            boolean isSent = getUrl().getMethodParameter(methodName, Constants.SENT_KEY, false);
            currentClient.send(inv, isSent);
            RpcContext.getContext().setFuture(null);
            return new RpcResult();
        //分支2: 如果是异步且需要返回值, 意味着要提供给用户一个future: RpcContext.getContext().getFuture()
            //用户才能通过此方法获取future再处理. 如果用户并不需要就要使用 分支1. 免得dubbo给你维护个future. 浪费性能
        } else if (isAsync) {
            ResponseFuture future = currentClient.request(inv, timeout);
            RpcContext.getContext().setFuture(new FutureAdapter<Object>(future));
            return new RpcResult();
        } else {
            RpcContext.getContext().setFuture(null);
            //分支3, 同步, 当然也不用futrue.
            // 这里的get()会让future陷入有条件的限时等待, 或者说 超时或者被signal有结果会返回
            return (Result) currentClient.request(inv, timeout).get();
        }
        // ps1: 超时对每个分支都需要, 所以还是需要一个定时任务(RemotingInvocationTimeoutScan 一个线程sleep 30毫秒轮询, 2.7版本是使用时间轮)去检查有条件的触发超时返回. (当然, 如果是同步调用本身get就自带超时属性, 个人认为, 同步的不需要放在时间轮)
        // ps2: 超时时间, 只有一个, 在生成协议的时候就决定了(由一定的优先级取出决胜者)
    } catch (TimeoutException e) {
        throw new RpcException(RpcException.TIMEOUT_EXCEPTION, "Invoke remote method timeout. method: " + invocation.getMethodName() + ", provider: " + getUrl() + ", cause: " + e.getMessage(), e);
    } catch (RemotingException e) {
        throw new RpcException(RpcException.NETWORK_EXCEPTION, "Failed to invoke remote method: " + invocation.getMethodName() + ", provider: " + getUrl() + ", cause: " + e.getMessage(), e);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值