Dubbo服务之间的调用是同步的吗?

 

dubbo 问题总结

https://blog.youkuaiyun.com/u010627840/article/details/99305885

 

1.服务调用在哪里

1.1 消费者调用流程

消费者的调用流程如下(dubbo2.7.3)

proxy0#sayHello(String)
  —> InvokerInvocationHandler#invoke(Object, Method, Object[])
    —> MockClusterInvoker#invoke(Invocation)  // mock 降级
      —> AbstractClusterInvoker#invoke(Invocation)   
        —> FailoverClusterInvoker#doInvoke(Invocation, List<Invoker<T>>, LoadBalance)  // 集群容错,负载均衡
          —> Filter#invoke(Invoker, Invocation)  // 包含多个 Filter 调用
            —> ListenerInvokerWrapper#invoke(Invocation) 
              —> AbstractInvoker#invoke(Invocation) 
                —> DubboInvoker#doInvoke(Invocation)   
                  —> ReferenceCountExchangeClient#request(Object, int)   
                    —> HeaderExchangeClient#request(Object, int)
                      —> HeaderExchangeChannel#request(Object, int)
                        —> AbstractPeer#send(Object)
                          —> AbstractClient#send(Object, boolean)
                            —> NettyChannel#send(Object, boolean)
                              —> NioClientSocketChannel#write(Object)

DubboInvoker 的doInvoke方法(dubbo2.7.3)

首先判断是否为oneWay,也就是单向通信,并获取服务调用超时时间。

DubboInvoker内部默认是异步调用的,但是它的上层封装AsyncToSyncInvoker默认是同步调用的。(dubbo当前为2.7.3)

DubboInvoker的上层Invoker封装为AsyncToSyncInvoker

默认为SYNC模式,如果返回值不是特殊处理的话

invocation.setInvokeMode(RpcUtils.getInvokeMode(url, invocation));
 public static InvokeMode getInvokeMode(URL url, Invocation inv) {
        if (isReturnTypeFuture(inv)) {
            return InvokeMode.FUTURE;
        } else if (isAsync(url, inv)) {
            return InvokeMode.ASYNC;
        } else {
            return InvokeMode.SYNC;
        }
    }

 若返回值实现CompletableFuture接口,代表异步处理

public static boolean isReturnTypeFuture(Invocation inv) {
    Class<?> clazz;
    if (inv instanceof RpcInvocation) {
        clazz = ((RpcInvocation) inv).getReturnType();
    } else {
        clazz = getReturnType(inv);
    }
    return (clazz != null && CompletableFuture.class.isAssignableFrom(clazz)) || isGenericAsync(inv);
}

若指定async为true ,代表异步

public static boolean isAsync(URL url, Invocation inv) {
    boolean isAsync;
    if (Boolean.TRUE.toString().equals(inv.getAttachment(ASYNC_KEY))) {
        isAsync = true;
    } else {
        isAsync = url.getMethodParameter(getMethodName(inv), ASYNC_KEY, false);
    }
    return isAsync;
}

 

asyncResult.get(Integer.MAX_VALUE, TimeUnit.MILLISECONDS);

这一行代码表面需要强行等待服务端结果返回

@Override
public Result invoke(Invocation invocation) throws RpcException {
    Result asyncResult = invoker.invoke(invocation);

    try {
        if (InvokeMode.SYNC == ((RpcInvocation) invocation).getInvokeMode()) {
            asyncResult.get(Integer.MAX_VALUE, TimeUnit.MILLISECONDS);
        }
    } catch (InterruptedException e) {
        throw new RpcException("Interrupted unexpectedly while waiting for remoting result to return!  method: " + invocation.getMethodName() + ", provider: " + getUrl() + ", cause: " + e.getMessage(), e);
    }

 

1.2 异步调用流程图 

1) 用户线程调用方法

2) IO线程将请求发送到服务端

3) IO线程setFuture

4)  用户线程执行getFuture获取结果,若为空,通过wait方法等待 .

CompletableFuture,提供了非常强大的Future的扩展功能,可以帮助我们简化异步编程的复杂性,提供了函数式编程的能力,可以通过回调的方式处理计算结果,并且提供了转换和组合CompletableFuture的方法。

5) 服务端响应结果,并写入Future

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值