You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@dubbo.apache.org by GitBox <gi...@apache.org> on 2021/08/16 09:58:57 UTC

[GitHub] [dubbo] qixiaobo commented on issue #8515: Dubbo ProviderConsumerRegTable class cause outOfMemory while no provider available exception occurs

qixiaobo commented on issue #8515:
URL: https://github.com/apache/dubbo/issues/8515#issuecomment-899382144


   I found this in ReferenceConfig
   ```java
   
               if (urls.size() == 1) {
                   invoker = refprotocol.refer(interfaceClass, urls.get(0));
               } else {
                   List<Invoker<?>> invokers = new ArrayList<Invoker<?>>();
                   URL registryURL = null;
                   for (URL url : urls) {
                       invokers.add(refprotocol.refer(interfaceClass, url));
                       if (Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) {
                           registryURL = url; // use last registry url
                       }
                   }
                   if (registryURL != null) { // registry url is available
                       // use AvailableCluster only when register's cluster is available
                       URL u = registryURL.addParameterIfAbsent(Constants.CLUSTER_KEY, AvailableCluster.NAME);
                       invoker = cluster.join(new StaticDirectory(u, invokers));
                   } else { // not a registry url
                       invoker = cluster.join(new StaticDirectory(invokers));
                   }
               }
           }
   
           Boolean c = check;
           if (c == null && consumer != null) {
               c = consumer.isCheck();
           }
           if (c == null) {
               c = true; // default true
           }
           if (c && !invoker.isAvailable()) {
               // make it possible for consumer to retry later if provider is temporarily unavailable
               initialized = false;
               throw new IllegalStateException("Failed to check the status of the service " + interfaceName + ". No provider available for the service " + (group == null ? "" : group + "/") + interfaceName + (version == null ? "" : ":" + version) + " from the url " + invoker.getUrl() + " to the consumer " + NetUtils.getLocalHost() + " use dubbo version " + Version.getVersion());
           }
           if (logger.isInfoEnabled()) {
               logger.info("Refer dubbo service " + interfaceClass.getName() + " from url " + invoker.getUrl());
           }
           // create service proxy
           return (T) proxyFactory.getProxy(invoker);
       }
   ```
   We may see like this since "No provider available" 
   But with this code <code>refprotocol.refer</code> It may work below
   ```java
    private <T> Invoker<T> doRefer(Cluster cluster, Registry registry, Class<T> type, URL url) {
           RegistryDirectory<T> directory = new RegistryDirectory<T>(type, url);
           directory.setRegistry(registry);
           directory.setProtocol(protocol);
           // all attributes of REFER_KEY
           Map<String, String> parameters = new HashMap<String, String>(directory.getUrl().getParameters());
           URL subscribeUrl = new URL(Constants.CONSUMER_PROTOCOL, parameters.remove(Constants.REGISTER_IP_KEY), 0, type.getName(), parameters);
           if (!Constants.ANY_VALUE.equals(url.getServiceInterface())
                   && url.getParameter(Constants.REGISTER_KEY, true)) {
               URL registeredConsumerUrl = getRegisteredConsumerUrl(subscribeUrl, url);
               registry.register(registeredConsumerUrl);
               directory.setRegisteredConsumerUrl(registeredConsumerUrl);
           }
           directory.subscribe(subscribeUrl.addParameter(Constants.CATEGORY_KEY,
                   Constants.PROVIDERS_CATEGORY
                           + "," + Constants.CONFIGURATORS_CATEGORY
                           + "," + Constants.ROUTERS_CATEGORY));
   
           Invoker invoker = cluster.join(directory);
           ProviderConsumerRegTable.registerConsumer(invoker, url, subscribeUrl, directory);
           return invoker;
       }
   ```
   You may see registerConsumer executed before.
   So while we never remove consumerInvokers 
   This may cause oom


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org