No provider available issue
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能复现此问题,不确定我的分析是否合理?
Please translate this issue into English :)
Do you mean that you export and refer the same service in the same process?
When initiated together by consumers and providers,after consumer run
notifySubscriber(url, listener, allCorrespondingInstanceList);
provider registed with nacos, and then consumer run
for (String serviceName : serviceNames) {
subscribeEventListener(serviceName, url, listener);
}
so it seems like consumer miss nacos notify because provider registed before consumer subscribe.
当provider的注册时机是发生在consumer拉取和订阅注册中心之间时,consumer会获取不到provider的信息. consumer先订阅,在拉取似乎能解决这个问题.
When the provider's registration timing occurs between the consumer pulling and subscribing to the registration center, the consumer will not be able to obtain the provider's information. The consumer subscribes first and pulls later, which seems to solve this problem.
pls assign to me. @AlbumenJ
I think this has been fixed in the latest 3.2.x version.
In org/apache/dubbo/config/deploy/DefaultModuleDeployer.java:183
In org/apache/dubbo/config/deploy/DefaultModuleDeployer.java:183
i think there is also exist the problem, the case is come from.
for (String serviceName : serviceNames) {
List<Instance> instances =
namingService.getAllInstances(serviceName, getUrl().getGroup(Constants.DEFAULT_GROUP));
notifySubscriber(url, serviceName, listener, instances);
}
for (String serviceName : serviceNames) {
subscribeEventListener(serviceName, url, listener);
}
namingService.getAllInstances(serviceName, getUrl().getGroup(Constants.DEFAULT_GROUP));
When there is no provider, The final effect of this code is to obtain the instance and subscribe. the subscription at this time has side effects. The reason is that the listener is not registered.
Before the listener is registered, if the service provider registration message is received, Then the message will be lost.
In org/apache/dubbo/config/deploy/DefaultModuleDeployer.java:183
i think there is also exist the problem, the case is come from.
for (String serviceName : serviceNames) { List<Instance> instances = namingService.getAllInstances(serviceName, getUrl().getGroup(Constants.DEFAULT_GROUP)); notifySubscriber(url, serviceName, listener, instances); } for (String serviceName : serviceNames) { subscribeEventListener(serviceName, url, listener); }namingService.getAllInstances(serviceName, getUrl().getGroup(Constants.DEFAULT_GROUP));
When there is no provider, The final effect of this code is to obtain the instance and subscribe. the subscription at this time has side effects. The reason is that the listener is not registered.
Before the listener is registered, if the service provider registration message is received, Then the message will be lost.
The reason is that the listener is not registered. Why?
listener registered happens in subscribeEventListener method. so when service provider registration message is received happens between notifySubscriber() and subscribeEventListener(), the message will be lost.
subscribeEventListener(serviceName, url, listener)
This is not depend on whether there have providers or not.
subscribeEventListener(serviceName, url, listener)
This is not depend on whether there have providers or not.
I think the code we are discussing should be in getAllInstances and subscribeEventListener. getAllInstances will have subscription operations when there is no provider , but at this time there not exist a listener.
This is not depend on whether there have providers or not.