dubbo2.6.1 consumer多组消费时provider使用默认组的问题

问题及现象

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;
    }
# dubbo 

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×