升级 dubbo 小心 default.version
上周遇到个关于升级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×tamp=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.取一次,也就是说version和default.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

来自:https://github.com/apache/dubbo/issues/5948
这个issue有一个相关联的修复,说是2.7.7已经修复了这个问题,于是我测试了一下2.7.7,很遗憾,还是报错,看了下修复代码

和2.6.6的兼容不一样,这里修复是在 URL 类的 valueOf 方法中添加兼容逻辑,修复者想的是所有注册中心上的URL字符串最终得经过这个方法才能成为URL对象,才能为dubbo所用。
想法是没错,但通过调试发现并不是每个URL对象都来自valueOf方法,2.7.7中订阅时对提供者的URL进行处理的是URLStrParser类的parseEncodedStr方法,所以这个修复就是无效的了。
关于作者:专注后端的中间件开发,公众号"捉虫大师"作者,关注我,给你最纯粹的技术干货

升级 dubbo 小心 default.version的更多相关文章
- Tomcat启动服务报错:Unknown version string [3.1]. Default version will be used.
用Intellij IDEA 部署Web项目,Tomcat启动后报错Unknown version string [3.1]. Default version will be used. 作者的问题出 ...
- 关于升级程序版本时version与build修改的问题
CHENYILONG Blog 关于升级程序版本时version与build修改的问题 #问题#从V1.0升级到V1.0.1.version是一定要改的,那么build需要修改吗? #解答#一般习惯上 ...
- org.apache.tomcat.util.descriptor.web.WebXml.setVersion Unknown version string [4.0]. Default version will be used.报错
org.apache.tomcat.util.descriptor.web.WebXml.setVersion Unknown version string [4.0]. Default versio ...
- Could not find JSON in http://updates.jenkins-ci.org/update-center.json?id=default&version=2.7.4
14-Sep-2016 21:43:58.241 INFO [Download metadata thread] hudson.model.AsyncPeriodicWork$1.run Finish ...
- Tomcat启动服务报错:Unknown version string [4.0]. Default version will be used.
Tomcat.jdk.web.xml 对应关系: 版本对应错误,更换便可.(版本往下兼容) web.xml——version2.2——JDK1.1——Tomcat3.3 web.xml——versio ...
- CentOS6.5升级autoconf版本 Autoconf version 2.64 or higher is required
安装软件时提示说需要Autoconf 2.64或更高的版本 [root@BobServerStation twemproxy]# autoconf configure.ac:8: error: Aut ...
- Dubbo原理剖析 之 @DubboReference.version设置为*
原文链接 Dubbo原理剖析 之 @DubboReference.version设置为* 1 背景 Dubbo在消费端提供了一个功能,即将消费者的版本号指定为*,那么不管服务端的接口版本是啥,都可以调 ...
- Dubbo -- 系统学习 笔记 -- 配置参考手册
Dubbo -- 系统学习 笔记 -- 目录 配置参考手册 <dubbo:service/> <dubbo:reference/> <dubbo:protocol/> ...
- dubbo 官方参考手册~备案(防止哪天阿里一生气把dubbo给删除了)
首页 || 下载 || 用户指南 || 开发者指南 || 管理员指南 || 培训文档 || 常见问题解答 || 发布记录 || 发展路线 || 社区 E ...
随机推荐
- PHP的rar解压读取扩展包学习
作为压缩解压方面的扩展学习,两大王牌压缩格式 rar 和 zip 一直是计算机领域的压缩终结者.rar 格式的压缩包是 Windows 系统中有接近统治地位的存在,今天我们学习的 PHP 扩展就是针对 ...
- Docker DevOps实战:Docker+Jenkins+Python+Pytest+Allure(2)- Jenkins初始化、Jenkins插件、Jenkins配置、自动化测试
Jenkins初始化 step-1 访问Jenkins http://ip:80 step-2 查看密码.输入密码 # 方式一:通过查看容器日志 [root@localhost ~]# docker ...
- 『GoLang』接口
接口是什么 Go 语言不是一种 "传统" 的面向对象编程语言:它里面没有类和继承的概念. 但是 Go 语言里有非常灵活的 接口 概念,通过它可以实现很多面向对象的特性.接口提供了一 ...
- VMware虚拟机常见问题(针对目前我所学的而言,还会不断更新)
VMware虚拟机常见问题(针对目前我所学的而言,还会不断更新) 自己电脑的telnet Client是否打开 在控制面板->程序->打开或关闭Windows功能 虚拟机的telnet是否 ...
- python二级 第八套
第一部分 基本操作 第一题 1. 第二题 1. 字符串的索引 和列表的索引 一样使用 2. 这俩者有什么区别 3. 我的意思想说 切片 里面没有冒号 就是表示取这个索引的 字 ...
- 鸿蒙内核源码分析(进程管理篇) | 谁在管理内核资源 | 百篇博客分析OpenHarmonyOS | v2.07
百篇博客系列篇.本篇为: v02.xx 鸿蒙内核源码分析(进程管理篇) | 谁在管理内核资源 | 51.c.h .o 进程管理相关篇为: v02.xx 鸿蒙内核源码分析(进程管理篇) | 谁在管理内核 ...
- CometOJ-[Contest #10]鱼跃龙门【exgcd】
正题 题目链接:https://cometoj.com/problem/1479 题目大意 给出\(n\)求一个最小的\(x(x>0)\)满足 \[\left(\sum_{i=1}^xi\rig ...
- P4590-[TJOI2018]游园会【dp套dp】
正题 题目链接:https://www.luogu.com.cn/problem/P4590 题目大意 给出一个长度为\(m\)的字符串\(s\). 对于每个\(k\in[0,m]\)求有多少个长度为 ...
- YbtOJ-大收藏家【分层图,最大流】
正题 题目链接:https://www.ybtoj.com.cn/contest/117/problem/2 题目大意 \(n\)个人,每人有\(a_i\)个属于自己的物品.\(m\)次交换依次进行, ...
- 如何基于Security实现OIDC单点登录?
一.说明 本文主要是给大家介绍 OIDC 的核心概念以及如何通过对 Spring Security 的授权码模式进行扩展来实现 OIDC 的单点登录. OIDC 是 OpenID Connect 的简 ...