DUBBO源码学习(六)服务的调用过程

DUBBO源码学习(一)spi机制
DUBBO源码学习(二)注册中心源码解析
DUBBO源码学习(三)v2.7.8-服务的暴露过程
DUBBO源码学习(四)服务引用的过程
DUBBO源码学习(五)负载均衡策略

一、服务调用的入口

通过之前的服务引用的分析,可以知道服务在引用的时候最终会生成一个invoker,最终invoker的执行我们会通过InvokerInvocationHandler#invoker:

public class InvokerInvocationHandler implements InvocationHandler {
   

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
   
        // 拦截定义在 Object 类中的方法(未被子类重写),比如 wait/notify
        if (method.getDeclaringClass() == Object.class) {
   
            return method.invoke(invoker, args);
        }
        String methodName = method.getName();
        Class<?>[] parameterTypes = method.getParameterTypes();
        if (parameterTypes.length == 0) {
   
            // 如果 toString、hashCode 和 equals 等方法被子类重写了,这里也直接调用
            if ("toString".equals(methodName)) {
   
                return invoker.toString();
            } else if ("$destroy".equals(methodName)) {
   
                invoker.destroy();
                return null;
            } else if ("hashCode".equals(methodName)) {
   
                return invoker.hashCode();
            }
        } else if (parameterTypes.length == 1 && "equals".equals(methodName)) {
   
            return invoker.equals(args[0]);
        }
        // 将方法和参数封装到 RpcInvocation 中
        RpcInvocation rpcInvocation = new RpcInvocation(method, invoker.getInterface().getName(), protocolServiceKey, args);
        String serviceKey = invoker.getUrl().getServiceKey();
        rpcInvocation.setTargetServiceUniqueName(serviceKey);

        // invoker.getUrl() 返回了消费者的url
        RpcContext.setRpcContext(invoker.getUrl());

        if (consumerModel != null) {
   
            rpcInvocation.put(Constants.CONSUMER_MODEL, consumerModel);
            rpcInvocation.put(Constants.METHOD_MODEL, consumerModel.getMethodModel(method));
        }

        return invoker.invoke(rpcInvocation).recreate();
    }
    
}

可以看到最后会调用到内部invoker对象的invoke 方法,这个invoker是带有服务降级的MockClusterInvoker:

public class MockClusterInvoker<T> implements ClusterInvoker<T> {
   
    
    @Override
    public Result invoke(Invocation invocation) throws RpcException {
   
        Result result = null;

        //mock的配置
        String value = getUrl().getMethodParameter(invocation.getMethodName(), MOCK_KEY, Boolean.FALSE.toString()).trim();
        if (value.length() == 0 || "false".equalsIgnoreCase(value)) {
   
            //无mock则调用其他invoker的invoke方法
            result = this.invoker.invoke(invocation);
        } else if (value.startsWith("force")) {
   
            if (logger.isWarnEnabled()) {
   
                logger.warn("force-mock: " + invocation.getMethodName() + " force-mock enabled , url : " + getUrl());
            }
            //force:direct 直接执行mock逻辑不发起远程调用
            result = doMockInvoke(invocation, null);
        } else {
   
            //fail-mock 服务调用失败后执行mock
            try {
   
                result = this.invoker.invoke(invocation);

                //fix:#4585
                if(result.getException() != null && result.getException() instanceof RpcException){
   
                    RpcException rpcException= (RpcException)result.getException();
                    if(rpcException.isBiz()){
   
                        throw  rpcException;
                    }else {
   
                        //调用失败的mock逻辑
                        result = doMockInvoke(invocation, rpcException);
                    }
                }

            } catch (RpcException e) {
   
                if (e.isBiz()) {
   
                    throw e;
                }

                if (logger.isWarnEnabled()) {
   
                    logger.warn("fail-mock: " + invocation.getMethodName() + " fail-mock enabled , url : " + getUrl(), e);
                }
                result = doMockInvoke(invocation, e);
            }
        }
        return result;
    }
    
    
     private Result doMockInvoke(Invocation invocation, RpcException e) {
   
        Result result = null;
        Invoker<T> minvoker;

        List<Invoker<T>> mockInvokers = selectMockInvoker(invocation);
        if (CollectionUtils.isEmpty(mockInvokers)) {
   
            minvoker = (Invoker<T>) new MockInvoker(getUrl(), directory.getInterface());
        } else {
   
            minvoker = mockInvokers.get(0);
        }
        try {
   
            result = minvoker.invoke(invocation);
        } catch (RpcException me) {
   
            if (me.isBiz()) {
   
                result = AsyncRpcResult.newDefaultAsyncResult(me.getCause(), invocation);
            } else {
   
                throw new RpcException(me.getCode(), getMockExceptionMessage(e, me), me.getCause());
            }
        } catch (Throwable me) {
   
            throw new RpcException(getMockExceptionMessage(e, me), me.getCause());
        }
        return result;
    }
    
    
}

可以看到我们又进入了 minvoker.invoke方法,这次的invoke会调用到clusterInvoke,也就是上文分析的容错机制的处理的地方。最后我们会调用到AbstractInvoker#invoke方法:

public abstract class AbstractInvoker<T> implements Invoker<T> {
   
    
    @Override
    public Result invoke(Invocation inv) throws RpcException {
   
        // if invoker is destroyed due to address refresh from registry, let's allow the current invoke to proceed
        if (destroyed.get()) {
   
            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(attachment)) {
   
            // 设置 attachment
            invocation.addObjectAttachmentsIfAbsent(attachment);
        }

        Map
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值