问题及现象
consumer订阅多组provider,即consumer的group为*或者,分隔的多组。
provider下面两种配置会有不同表现!
<dubbo:provider group="${dubbo.provider.group}"/>
<dubbo:service interface="com.tc.dubbo.api.Provider1"
                   ref="provider1Impl"
                   />
上面有问题, 会导致consumer找不到provider!
下面的这种没问题!
<dubbo:service interface="com.tc.dubbo.api.Provider1"
                   ref="provider1Impl"
                   group="${dubbo.provider.group}"
                   />
原因
provider服务上线notify consumer的时有一个merge provider参数的过程如下
RegistryDirectory.java

merge的时候有bug
 
即provider显式的配置group时merge完之后的provider url就是正确的。如果不显式的配置group, merge完了之后provider group就是consumer的group(*或者,分隔),会导致consumer端找不到provider!
解决方案
simple but stupid
约定provider必须显式的配置group!
provider端解决
SPI扩展一个AbstractConfigurator
将默认的group,动态修改为显式的group. 这样merge之后就不会有问题了。
public class XxDubboConfigurator extends AbstractConfigurator {
    private static final Logger LOGGER = LoggerFactory.getLogger(XxDubboConfigurator.class);
    public XxDubboConfigurator(URL url) {
        super(url);
    }
    @Override
    public URL doConfigure(URL currentUrl, URL configUrl) {
        if (!Constants.DUBBO_VERSION_KEY.equals(currentUrl.getProtocol())) {
            return currentUrl;
        }
        String side = currentUrl.getParameter(Constants.SIDE_KEY);
        if (Constants.PROVIDER.equals(side)) {
            String defaultGroupKey = Constants.DEFAULT_KEY_PREFIX + Constants.GROUP_KEY;
            String defaultGroup = currentUrl.getParameter(defaultGroupKey);
            if (!currentUrl.getParameters().containsKey(Constants.GROUP_KEY) && defaultGroup != null) {
                currentUrl = currentUrl.addParameterAndEncoded(Constants.GROUP_KEY, defaultGroup);
                LOGGER.info("provider修改后的group:{} full url:{}", defaultGroup, currentUrl.toFullString());
            }
            return currentUrl;
        }
        return currentUrl;
    }
}
consumer端解决
SPI扩展一个FailbackRegistry
consumer notify时动态修改provider url, 也可以解决后续merge url的bug!
    private List<URL> toUrlsWithoutEmpty(URL consumer, List<String> providers) {
        List<URL> urls = new ArrayList<URL>();
        if (providers != null && providers.size() > 0) {
            for (String provider : providers) {
                provider = URL.decode(provider);
                if (provider.contains("://")) {
                    URL url = URL.valueOf(provider);
                    if (UrlUtils.isMatch(consumer, url)) {
                        urls.add(providerGroupEnhance(url));
                    }
                }
            }
        }
        return urls;
    }
    private URL providerGroupEnhance(URL url) {
        if (!Constants.DUBBO_VERSION_KEY.equals(url.getProtocol())) {
            return url;
        }
        String defaultGroupKey = Constants.DEFAULT_KEY_PREFIX + Constants.GROUP_KEY;
        String defaultGroup = url.getParameter(defaultGroupKey);
        if (!url.getParameters().containsKey(Constants.GROUP_KEY) && defaultGroup != null) {
            url = url.addParameterAndEncoded(Constants.GROUP_KEY, defaultGroup);
            logger.info("provider修改后的group:{} full url:{}", defaultGroup, url.toFullString());
        }
        return url;
    }