dubbo源码分析-创建Registry

dubbo在跟注册中心(Registry)通信之前,首先要创建Registry Proxy,才能subscribe(订阅服务)和register(注册服务)。如下图的6,8。

在dubbo中,Registry Proxy和其他代理没有什么不同,同样是Registry的一个映像。因此创建普通Proxy的过程同样适用于Registry Proxy。

public Registry createRegistry(URL url) {
        url = getRegistryURL(url);
        List urls = new ArrayList();
        urls.add(url.removeParameter(Constants.BACKUP_KEY));
        String backup = url.getParameter(Constants.BACKUP_KEY);
        if (backup != null && backup.length() > 0) {
            String[] addresses = Constants.COMMA_SPLIT_PATTERN.split(backup);
            for (String address : addresses) {
                urls.add(url.setAddress(address));
            }
        }
        RegistryDirectory directory = new RegistryDirectory(RegistryService.class, url.addParameter(Constants.INTERFACE_KEY, RegistryService.class.getName()).addParameterAndEncoded(Constants.REFER_KEY, url.toParameterString()));// 1
        Invoker registryInvoker = cluster.join(directory); // 2
        RegistryService registryService = proxyFactory.getProxy(registryInvoker); // 3
        DubboRegistry registry = new DubboRegistry(registryInvoker, registryService); // 4 
        directory.setRegistry(registry); // 5
        directory.setProtocol(protocol); // 6
        directory.notify(urls); // 7
        directory.subscribe(new URL(Constants.CONSUMER_PROTOCOL, NetUtils.getLocalHost(), 0, RegistryService.class.getName(), url.getParameters())); // 8
        return registry;
    }

先看1,创建了一个RegistryDirectory,可以调用RegistryDirectory的doList(Invocation invocation)方法来获得invocation的所有Invoker。其中invocation只需要给出调用的方法名称,Invoker则负责发送调用请求和接收返回结果,里面封装了所有的通信,序列化细节。RegistryDirectory又是如何根据invocation来得到invoker的呢?RegistryDirectory包含一个subscribe方法,用来向Registry请求感兴趣的服务的调用地址,然后Registry会回调RegistryDirectory,也就是notify方法,notify方法就会把这些服务的地址进一步封装成invoker,并且缓存起来。这样调用doList的时候直接根据invocation的方法名来找对应的invoker就可以了。

再看2,因为RegistryDirectory的doList返回的invocation是一个list列表,也就是可能会存在多个可用的服务实现,那么就需要一个负载均衡机制来决定调用哪个服务,可以看到cluster的invoke方法里都有一个loadbalance来具体实现选择。

第3步很简单,构造RegistryService代理,所有的请求通过cluster最后落到directory的invoker上面,具体负责RegistryService里各种接口方法的调用。

4 实现一个dubboRegistry,跟RegistryService区别是,dubboRegistry里面实现了failback机制,如果某个方法调用失败,那么会有一个线程来重复的调用,直到调用成功。

5 是用来设置Registry  Proxy,RegistryDirectory使用它来连接Registry,请求感兴趣的服务地址。

6 设置Protocol,RegistryDirectory使用它来把url转换成invoker。

7 是初始化Registry Proxy,使用consumer端的配置信息来连接Registry,调用完成后Registry的invoker就生成了。这一步就是Registry Proxy同普通的Service Proxy不一致的地方 。

8 重新注册Registry服务,这样就可以获得Registry的Provider端的配置信息。

生成Registry代理和普通代理的区别是:普通代理需要Registry代理同Registry通信,订阅服务和生成invoker。但是Registry代理则只能先通过consumer端的配置信息生成一个临时的代理,然后在notify回调时重新生成Registry代理(包含了Provider端的参数以及路由信息)。



你可能感兴趣的:(Dubbo)