apache/dubbo

No provider available issue

Open

#13,675 创建于 2024年1月18日

在 GitHub 查看
 (14 评论) (0 反应) (0 负责人)Java (26,453 fork)batch import
component/sdkhelp wantedtype/bug

仓库指标

Star
 (41,524 star)
PR 合并指标
 (平均合并 7天 14小时) (30 天内合并 20 个 PR)

描述

When initiated together by consumers and providers

private void doSubscribe(final URL url, final NotifyListener listener, final Set<String> serviceNames) {
        execute(namingService -> {
            if (isServiceNamesWithCompatibleMode(url)) {
                List<Instance> allCorrespondingInstanceList = new ArrayList<>();

                /**
                 * Get all instances with serviceNames to avoid instance overwrite and but with empty instance mentioned
                 * in https://github.com/apache/dubbo/issues/5885 and https://github.com/apache/dubbo/issues/5899
                 *
                 * namingService.getAllInstances with {@link org.apache.dubbo.registry.support.AbstractRegistry#registryUrl}
                 * default {@link DEFAULT_GROUP}
                 *
                 * in https://github.com/apache/dubbo/issues/5978
                 */
                for (String serviceName : serviceNames) {
                    List<Instance> instances = namingService.getAllInstances(serviceName,
                            getUrl().getParameter(GROUP_KEY, Constants.DEFAULT_GROUP));
                    NacosInstanceManageUtil.initOrRefreshServiceInstanceList(serviceName, instances);
                    allCorrespondingInstanceList.addAll(instances);
                }
                notifySubscriber(url, listener, allCorrespondingInstanceList);
                for (String serviceName : serviceNames) {
                    subscribeEventListener(serviceName, url, listener);
                }
            } else {
                List<Instance> instances = new LinkedList<>();
                for (String serviceName : serviceNames) {
                    instances.addAll(namingService.getAllInstances(serviceName
                            , getUrl().getParameter(GROUP_KEY, Constants.DEFAULT_GROUP)));
                    notifySubscriber(url, listener, instances);
                    subscribeEventListener(serviceName, url, listener);
                }
            }

        });
    }

after consumer run

for (String serviceName : serviceNames) {
                    List<Instance> instances = namingService.getAllInstances(serviceName,
                            getUrl().getParameter(GROUP_KEY, Constants.DEFAULT_GROUP));
                    NacosInstanceManageUtil.initOrRefreshServiceInstanceList(serviceName, instances);
                    allCorrespondingInstanceList.addAll(instances);
                }
                notifySubscriber(url, listener, allCorrespondingInstanceList);

the field forbidden in DynamicDirectory become true, at this time, provider register to nacos, and then consumer run

for (String serviceName : serviceNames) {
                    subscribeEventListener(serviceName, url, listener);
                }

so it seems that consumer miss nacos notify because provider registed before consumer subscribe it on nacos. cause forbidden is always true.
这段代码之间,生产者注册到了nacos,此时,由于消费者还没向nacos监听服务,所以收不到通知,导致这个情况下forbidden属性不通过外力干涉,一直是true,导致调用no provider,我通过debug能复现此问题,不确定我的分析是否合理?

贡献者指南