dubbo-本地服务暴露与调用

2018-06-17  本文已影响14人  兴浩

1.本地服务暴露

默认情况下,每个dubbo服务都会被以InjvmProtocol注册到本地

1.1在ServiceConfig中的export中调用

1.2 其根据service的scope进行判断

可以通过设置scope来调整

<dubbo:service interface="com.alibaba.dubbo.demo.DemoService" scope="local|remote" ref="demoService"/>

1.3 exportLocal

根据url的protocol的injvm参数来获取InjvmProtocol协议对象,来暴露服务

    public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
        return new InjvmExporter<T>(invoker, invoker.getUrl().getServiceKey(), exporterMap);
    }

2.服务引用

2.1判断是否jvm引用

在ReferenceConfig的createProxy会调用InjvmProtocol.getInjvmProtocol()的isInjvmRefer方法,是否是jvm引用

  1. 由于是同一个jvm进程,所以InjvmProtocol.getInjvmProtocol()拿到的对象和服务暴露的InjvmProtocol对象是同一个
    2.服务暴露时,已经将对象存储在exporterMap变量中,getExporter方法可以根据url参数获取export,isInjvmRefer以此来作为判断逻辑
    public boolean isInjvmRefer(URL url) {
        final boolean isJvmRefer;
        String scope = url.getParameter(Constants.SCOPE_KEY);
        // Since injvm protocol is configured explicitly, we don't need to set any extra flag, use normal refer process.
        if (Constants.LOCAL_PROTOCOL.toString().equals(url.getProtocol())) {
            isJvmRefer = false;
        } else if (Constants.SCOPE_LOCAL.equals(scope) || (url.getParameter("injvm", false))) {
            // if it's declared as local reference
            // 'scope=local' is equivalent to 'injvm=true', injvm will be deprecated in the future release
            isJvmRefer = true;
        } else if (Constants.SCOPE_REMOTE.equals(scope)) {
            // it's declared as remote reference
            isJvmRefer = false;
        } else if (url.getParameter(Constants.GENERIC_KEY, false)) {
            // generic invocation is not local reference
            isJvmRefer = false;
        } else if (getExporter(exporterMap, url) != null) {
            // by default, go through local reference if there's the service exposed locally
            isJvmRefer = true;
        } else {
            isJvmRefer = false;
        }
        return isJvmRefer;
    }

3.Invoke

直接调用exporter的Invoker来执行

    public Result doInvoke(Invocation invocation) throws Throwable {
        Exporter<?> exporter = InjvmProtocol.getExporter(exporterMap, getUrl());
        if (exporter == null) {
            throw new RpcException("Service [" + key + "] not found.");
        }
        RpcContext.getContext().setRemoteAddress(NetUtils.LOCALHOST, 0);
        return exporter.getInvoker().invoke(invocation);
    }

参考:
https://www.jianshu.com/p/1c53767359c6

上一篇下一篇

猜你喜欢

热点阅读