美文网首页
升级dubbo,小心default.version

升级dubbo,小心default.version

作者: 捉虫大师 | 来源:发表于2021-04-02 20:06 被阅读0次

上周遇到个关于升级dubbo 2.6 到2.7的兼容性问题,差点造成线上故障,这里记录下,也给大家提个醒。

问题回放

有一个接口的提供方(dubbo 2.6.6)这么配置接口的版本号

<dubbo:provider version="1.0.0"/>

消费方(也是dubbo 2.6.6)的reference这么配置

<dubbo:reference id="sampleService" version="1.0.0" check="false" interface="com.newboo.basic.api.SampleService"/>

然后升级消费方的dubbo版本,经过一通操作将消费者升级到dubbo 2.7.3,预发测试时发现调用报No provider,还好是在测试时发现,不然后果不堪设想

No provider available from registry 127.0.0.1:2181

根因分析

查看注册到注册中心的URL是这样

dubbo://10.0.0.6:20880/com.newboo.basic.api.SampleService?anyhost=true&application=ddog-provider-this-two&bind.ip=10.0.0.6&bind.port=20880&default.version=1.0.0&dubbo=2.0.2&generic=false&interface=com.newboo.basic.api.SampleService&methods=getByUid&owner=roshilikang&pid=82799&qos.accept.foreign.ip=true&qos.enable=true&side=provider&timestamp=1616848403414

可以看到它没有version字段,取而代之的是default.version字段

看一下dubbo中匹配version这个逻辑,位置在org.apache.dubbo.common.utils.UrlUtils类的isMatch方法,摘出重点部分

String consumerGroup = consumerUrl.getParameter(GROUP_KEY);
String consumerVersion = consumerUrl.getParameter(VERSION_KEY);
String consumerClassifier = consumerUrl.getParameter(CLASSIFIER_KEY, ANY_VALUE);

String providerGroup = providerUrl.getParameter(GROUP_KEY);
String providerVersion = providerUrl.getParameter(VERSION_KEY);
String providerClassifier = providerUrl.getParameter(CLASSIFIER_KEY, ANY_VALUE);
return (ANY_VALUE.equals(consumerGroup) || StringUtils.isEquals(consumerGroup, providerGroup) || StringUtils.isContains(consumerGroup, providerGroup))
        && (ANY_VALUE.equals(consumerVersion) || StringUtils.isEquals(consumerVersion, providerVersion))
        && (consumerClassifier == null || ANY_VALUE.equals(consumerClassifier) || StringUtils.isEquals(consumerClassifier, providerClassifier));

逻辑很简单,就是provider和consumer URL上的version字段得匹配上,提供者没有version字段,只有default.version字段,很显然调用时报错。

但之前2.6.6是没有问题的,为什么?看了下2.6.6的实现,代码也是一样,但点进providerUrl.getParameter(VERSION_KEY);,发现它的实现不简单

public String getParameter(String key) {
    String value = parameters.get(key);
    if (value == null || value.length() == 0) {
        value = parameters.get(Constants.DEFAULT_KEY_PREFIX + key);
    }
    return value;
}

先取key对应的值,取不到时,再加个前缀default.取一次,也就是说versiondefault.version两者只要有一个有值即可(version优先)。

反观2.7.3的实现就非常耿直

public String getParameter(String key) {
    return parameters.get(key);
}

所以,这就直接导致了2.7.3调用2.6.6的default.version接口报错,类似的group也存在这个问题,甚至还有一些如timeout等参数都可能会失效。

这个问题还是比较明显,应该有人遇到,搜索了一下github,果然让我找到了相关的issue

img1.jpg

来自:https://github.com/apache/dubbo/issues/5948

这个issue有一个相关联的修复,说是2.7.7已经修复了这个问题,于是我测试了一下2.7.7,很遗憾,还是报错,看了下修复代码

img2.jpg

和2.6.6的兼容不一样,这里修复是在 URL 类的 valueOf 方法中添加兼容逻辑,修复者想的是所有注册中心上的URL字符串最终得经过这个方法才能成为URL对象,才能为dubbo所用。

想法是没错,但通过调试发现并不是每个URL对象都来自valueOf方法,2.7.7中订阅时对提供者的URL进行处理的是URLStrParser类的parseEncodedStr方法,所以这个修复就是无效的了。

相关文章

  • 升级dubbo,小心default.version

    上周遇到个关于升级dubbo 2.6 到2.7的兼容性问题,差点造成线上故障,这里记录下,也给大家提个醒。 问题回...

  • Dubbo 常见问题

    Dubbo---升级Dubbo2.7.13依赖问题 原文链接:https://blog.csdn.net/chih...

  • DUBBO SPI实现核心-ExtensionLoader

    概念 dubbo spi是dubbo对JDK spi的升级,针对JDK spi的一些弱势进行了优化,官网的介绍如下...

  • 注意dubb2.7.4版本的一个bug

    原因 今天给公司搭建一个新项目,所以想升级dubbo版本,现在dubbo最新版本是2.7.4.1, 当时想可能不太...

  • dubbo优雅宕机

    最近遇到了一个问题,由于我们的服务采用dubbo框架,却近几次服务升级,总出现dubbo宕机的情况,经过一番排查,...

  • Dubbo的特点

    1.介绍 DUBBO有良好的连通性、健壮性、伸缩性、升级性。结合dubbo可以相对于单体系统提升系统整体的扩展性 ...

  • Android Studio打开项目提示 Connection

    Android Studio每次升级都会有坑,所以如果没有特殊需要能不升级就不要升级,小心入坑因为手残不小心设置了...

  • 2019-11-14 什么是dubbo的泛化调用

    一般调用,Dubbo必须依赖服务端提供的api包,如果服务端升级了api包,客户端也必须跟着升级。 泛化接口调用方...

  • DUBBO-POSTMAN(dubbo接口测试,dubbo场景测

    DUBBO-POSTMAN(dubbo接口测试,dubbo场景测试,dubbo集成测试) DUBBO-POSTMA...

  • dubbo记录

    目录 《dubbo入门》《dubbo管理控制台》《dubbo超时重传》《dubbo直连》《dubbo实现服务降级》...

网友评论

      本文标题:升级dubbo,小心default.version

      本文链接:https://www.haomeiwen.com/subject/ufbqkltx.html