Dubbo源码解析(三)-了解消费者的负载均衡等以及调用的补充

上篇文章https://blog.csdn.net/qq_38340127/article/details/112712044为当一个服务提供者直接进行request等,那么当有多个服务提供者,消费者是如何进行选择?

首先新增一个服务提供者:

provider1中暴露端口修改为20881

将两个服务都进行启动,消费者进行调试:

用zookeeper客户端进行查看(由于我在idea中安装插件无效。。。)

未启动消费者

消费者调用-客户端与服务端进行连接

对上篇中存在的部分遗漏进行添加:

在org.apache.dubbo.registry.zookeeper.ZookeeperRegistry#doSubscribe 方法中,会对provider进行订阅,其中主要方法为:

List<String> children = zkClient.addChildListener(path, zkListener);// 获取到当前节点下的所有监听对象

于是便得到了zookeeper的providers下的相关信息

                List<URL> urls = new ArrayList<>();
                for (String path : toCategoriesPath(url)) { //当是消费者进行订阅时,一共监听了对应的providers、configurators、routers
                    ConcurrentMap<NotifyListener, ChildListener> listeners = zkListeners.get(url);
                    if (listeners == null) {
                        zkListeners.putIfAbsent(url, new ConcurrentHashMap<>());
                        listeners = zkListeners.get(url);
                    }
                    ChildListener zkListener = listeners.get(listener);
                    if (zkListener == null) {
                        listeners.putIfAbsent(listener, (parentPath, currentChilds) -> ZookeeperRegistry.this.notify(url, listener, toUrlsWithEmpty(url, parentPath, currentChilds)));
                        zkListener = listeners.get(listener);
                    }
                    zkClient.create(path, false);
                    List<String> children = zkClient.addChildListener(path, zkListener);// 获取到当前节点下的所有监听对象
                    if (children != null) {
                        urls.addAll(toUrlsWithEmpty(url, path, children));
                    }
                }
                notify(url, listener, urls);//对url进行获取相关信息

然后是主要方法

    @Override
    protected void notify(URL url, NotifyListener listener, List<URL> urls) {
        if (url == null) {
            throw new IllegalArgumentException("notify url == null");
        }
        if (listener == null) {
            throw new IllegalArgumentException("notify listener == null");
        }
        try {
            doNotify(url, listener, urls);
        } catch (Exception t) {
            // Record a failed registration request to a failed list, retry regularly
            addFailedNotified(url, listener, urls);
            logger.error("Failed to notify for subscribe " + url + ", waiting for retry, cause: " + t.getMessage(), t);
        }
    }

其中urls信息如下(可以看到有两个服务提供者的dubbo信息):

继续发现封装成invoker的时候

org.apache.dubbo.registry.integration.RegistryDirectory#toInvokers发现指定的服务提供者url为

于是进行创建两个client进行与不同的provider进行连接。

消费者进行执行对应方法

根据上篇了解到消费者进行调用方法,就是根据invoker进行request的操作,

同时添加补充在org.apache.dubbo.rpc.cluster.support.FailoverClusterInvoker#doInvoke方法中有指定对应的重试次数

        int len = getUrl().getMethodParameter(methodName, RETRIES_KEY, DEFAULT_RETRIES) + 1;
        if (len <= 0) {
            len = 1;
        }//len代表重试次数  默认次数DEFAULT_RETRIES为2

那么该选择哪个client呢?

org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker#invoke

在获取对应的invoker时进行了负载均衡策略

    @O
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值