apache/dubbo

No provider available issue

Open

#13.675 aberto em 18 de jan. de 2024

Ver no GitHub
 (14 comments) (0 reactions) (0 assignees)Java (26.453 forks)batch import
component/sdkhelp wantedtype/bug

Métricas do repositório

Stars
 (41.524 stars)
Métricas de merge de PR
 (Mesclagem média 7d 14h) (20 fundiu PRs em 30d)

Description

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能复现此问题,不确定我的分析是否合理?

Guia do colaborador