程序员社区

dubbo 源码解析 3


title: dubbo 源码解析 3
date: 2020/05/27 10:45


本节内容

远程服务发布(注册中心版)

远程服务发布

dubbo 源码解析 3插图

tag1 proxyFactory.getInvoker()

这部分流程和本地发布的一模一样,可以回顾一下

tag2 protocol.export()

public org.apache.dubbo.rpc.Exporter export(org.apache.dubbo.rpc.Invoker arg0) throws org.apache.dubbo.rpc.RpcException {
    if (arg0 == null) throw new IllegalArgumentException("org.apache.dubbo.rpc.Invoker argument == null");
    if (arg0.getUrl() == null) throw new IllegalArgumentException("org.apache.dubbo.rpc.Invoker argument getUrl() == null");
    // 从Invoker 对象中获取到 url 对象
    org.apache.dubbo.common.URL url = arg0.getUrl();
    // 通过 url 对象获取协议
    String extName = ( url.getProtocol() == null ? "dubbo" : url.getProtocol() );
    if(extName == null) throw new IllegalStateException("Fail to get extension(org.apache.dubbo.rpc.Protocol) name from url(" + url.toString() + ") use keys([protocol])");
    org.apache.dubbo.rpc.Protocol extension = null;
    try {
        // 获取到对应协议的对象 ProtocolFilterWrapper
        extension = (org.apache.dubbo.rpc.Protocol)ExtensionLoader.getExtensionLoader(org.apache.dubbo.rpc.Protocol.class).getExtension(extName);
    }catch(Exception e){
        if (count.incrementAndGet() == 1) {
            logger.warn("Failed to find extension named " + extName + " for type org.apache.dubbo.rpc.Protocol, will use default extension dubbo instead.", e);
        }
        extension = (org.apache.dubbo.rpc.Protocol)ExtensionLoader.getExtensionLoader(org.apache.dubbo.rpc.Protocol.class).getExtension("dubbo");
    }

    // 执行协议对象的 export() 方法
    return extension.export(arg0);
}
dubbo 源码解析 3插图1
dubbo 源码解析 3插图2
dubbo 源码解析 3插图3
dubbo 源码解析 3插图4

这个发布器只有在 unexport 的时候才会用到(换句话说,DestroyableExporter 相当于 new 了一个空实现的 Exporter),在服务调用的时候用的都是最上面那个 dubbo 发布的发布器。

tag2.1 doLocalExport() --> dubbo 服务发布

dubbo 源码解析 3插图5

然后又经历了下面三个类的调用,最终到达了 DubboProtocol

dubbo 源码解析 3插图6

DubboProtocol:

dubbo 源码解析 3插图7
dubbo 源码解析 3插图8
dubbo 源码解析 3插图9
dubbo 源码解析 3插图10
这个门面里封装了寻找具体实例的动作,其实可以学一下

传入的 handler 是 DubboProtocol 的一个匿名内部类。

Exchanger:交换器,不知道在这里是做啥的

dubbo 源码解析 3插图11

这里还用了装饰者模式。

Transporter:运输者,不知道在这里是做啥的

dubbo 源码解析 3插图12
dubbo 源码解析 3插图13
dubbo 源码解析 3插图14
dubbo 源码解析 3插图15

上面代码多为赋值代码,不需要多讲。我们重点关注 doOpen 抽象方法,该方法需要子类实现。下面回到 NettyServer 中。

dubbo 源码解析 3插图16
dubbo 源码解析 3插图17

我们看一下这个 handler,最早可以追溯到 HeaderExchanger#bind() 中的new DecodeHandler(new HeaderExchangeHandler(handler)),其中 handler 是 DubboProtocol 的一个匿名内部类(其中 hander 本身就是 ChannelHandler 的子类,外面两层是装饰者)。

public class HeaderExchanger implements Exchanger {

    public static final String NAME = "header";

    ...

    @Override
    public ExchangeServer bind(URL url, ExchangeHandler handler) throws RemotingException {
        // 扩展一下 HeaderExchangeServer 的作用是开启心跳检测,检查服务是否存活
        return new HeaderExchangeServer(Transporters.bind(url, new DecodeHandler(new HeaderExchangeHandler(handler))));
    }

}
dubbo 源码解析 3插图18

tag2.2 register()

dubbo 源码解析 3插图19

tag2.2.1 registryFactory.getRegistry()

dubbo 源码解析 3插图20
dubbo 源码解析 3插图21
dubbo 源码解析 3插图22

默认的组是 /dubbo 对应着 zookeeper 中存的目录

tag2.2.2 registry.register()

dubbo 源码解析 3插图23
dubbo 源码解析 3插图24

zookeeper 相关的地方我们就不讲了

赞(0) 打赏
未经允许不得转载:IDEA激活码 » dubbo 源码解析 3

一个分享Java & Python知识的社区