Dubbo 2.7.1 踩坑记
Dubbo 2.7 版本增加新特性,新系统开始使用 Dubbo 2.7.1 尝鲜新功能。使用过程中不慎踩到这个版本的 Bug。
系统架构
Spring Boot 2.14-Release + Dubbo 2.7.1
现象
Dubbo 服务者启动成功,正常提供服务,消费者调用偶现失败的情况。错误如下图:

可以看出,主要原因为 cause: message can not send, because channel is closed。 但是检查提供者,却发现服务进程正常。
登陆 Dubbo admin 查看提供者服务,发现这个服务存在两个节点。

192.168.164.77 为测试服务器的 ip,提供者位于这台机器,而另一个 10.20.80.67 却是本地电脑的 IP,但是此时本地并未运行这个服务。
再次查看服务报错的原因,可以看到提供者调用l本地提供 RPC 的服务。由于本地服务已停止,导致调用失败。
这个问题在之前版本从未碰到,刚开始隐约记得 Dubbo 服务提供者注册使用 ZooKeeper 临时节点,服务断开,会删除该节点。
问题原因
在 Dubbo 主页搜索相关 issue,看到同样的问题 Dubbo-2.7.1 providers 重复注册.
查看相关回复,可以看到问题主要由于 dynamic 默认值变成 false ,而 2.7.1 之前版本默认不赋值,初始值为 null。

后续 PR 中已修复该问题 Fix issue 3785,修复代码将 dynamic 默认设置成 true。但是截止 20190515 该版本暂未发布。
源码分析
知道问题原因,这里我们从源码分析一下,为什么 dynamic 设置成 false 会导致该问题。
注:下面分析的是 Dubbo 2.7.1 的源码
下面我们使用 Dubbo xml 配置相关。
在 xml 配置中,可以在以下两个地方设置 dynamic 属性。

服务启动时将会使用 DubboNamespaceHandler 解析,注入 Spring 容器。

其中会将 provider 标签解析成 ProviderConfig 对象,service 标签解析成 ServiceBean 对象。

查看继承关系,可以看到以上两个类都继承 AbstractServiceConfig , dynamic 位于这个父对象中。

可以看到该字段默认值为 false。
接着查看 Dubbo 服务导出过程,位于 ServiceBean#export,略过其他代码,我们直接跳到关键 ServiceConfig#doExportUrlsFor1Protocol 。

可以看到这里调用了多次 appendParameters 方法。 这个方法将利用反射,获取对象的中所有字段信息,然后添加到 map 中。其中字段名字为键值,字段实际值为内容。此时 map 键值内容为:

可以看到 map 中还有一个 default.dynamic,大家翻看代码自己思考一下,为什么会出现这个?
接着我们跳到后面:

在这里会将上面得到 map 组装到 URL 对象中,然后再注册到注册中心。。
由于注册中心使用的是 ZooKeeper,所以这里将会使用 ZookeeperRegistry 实现类。

首先查看 url##getParameter 方法,这里 Constants.DYNAMIC_KEY 值为 dynamic。

该方法会先从 parameters 中根据键值取值。若不存在,会再根据 default 作为前缀拼接再次取值。若还不存在则使用传入的默认值。
查看此时的 parameters 对象。

url.getParameter(Constants.DYNAMIC_KEY, true) 返回为 false。
然后分析 zkClient#create 方法,

由于 ephemeral 为 false,所以这个服务注册到 ZooKeeper 的节点为持久节点。
临时节点,客户端断开,会话超时后,ZooKeeper 将会自动删除这个节点。zookeeper-faq
面试题:服务提供者能实现失效踢出是什么原理(高频题)
服务宕机的时候,该节点由于是持久节点会永远存在,而且当服务再次重启的时候会将重新注册一个新节点。这样就导致 ZooKeeper 中存在额外失效的节点,且该节点还无法自然消除(除非手动调用 ZooKeeper 删除节点方法)。
总结
由于 Dubbo 2.7.2 暂未发布,所以建议若想使用 Dubbo 2.7 新功能的同学,使用 2.7.0 版本。若现在正在使用 2.7.2 版本,也不要慌张。只要服务不是异常宕机或者使用 kill -9 强制杀死进程,以上的现象将不会碰到。正常服务关闭的时候,Dubbo 服务会主动去 ZooKeeper 注销该服务,并删除这个节点。
还未使用该版本的同学们,建议使用 2.7.0 或者等 2.7.2 发布以后,再使用。
Dubbo 2.7.1 踩坑记的更多相关文章
- Spark踩坑记——Spark Streaming+Kafka
[TOC] 前言 在WeTest舆情项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端,我们利用了spark strea ...
- Spark踩坑记——数据库(Hbase+Mysql)
[TOC] 前言 在使用Spark Streaming的过程中对于计算产生结果的进行持久化时,我们往往需要操作数据库,去统计或者改变一些值.最近一个实时消费者处理任务,在使用spark streami ...
- 【踩坑记】从HybridApp到ReactNative
前言 随着移动互联网的兴起,Webapp开始大行其道.大概在15年下半年的时候我接触到了HybridApp.因为当时还没毕业嘛,所以并不清楚自己未来的方向,所以就投入了HybridApp的怀抱. Hy ...
- Spark踩坑记——共享变量
[TOC] 前言 Spark踩坑记--初试 Spark踩坑记--数据库(Hbase+Mysql) Spark踩坑记--Spark Streaming+kafka应用及调优 在前面总结的几篇spark踩 ...
- Spark踩坑记——从RDD看集群调度
[TOC] 前言 在Spark的使用中,性能的调优配置过程中,查阅了很多资料,之前自己总结过两篇小博文Spark踩坑记--初试和Spark踩坑记--数据库(Hbase+Mysql),第一篇概况的归纳了 ...
- djangorestframework+vue-cli+axios,为axios添加token作为headers踩坑记
情况是这样的,项目用的restful规范,后端用的django+djangorestframework,前端用的vue-cli框架+webpack,前端与后端交互用的axios,然后再用户登录之后,a ...
- HttpWebRequest 改为 HttpClient 踩坑记-请求头设置
HttpWebRequest 改为 HttpClient 踩坑记-请求头设置 Intro 这两天改了一个项目,原来的项目是.net framework 项目,里面处理 HTTP 请求使用的是 WebR ...
- vue踩坑记
vue踩坑记 易错点 语法好难啊qwq 不要把'data'写成'date' 在v-html/v-bind中使用vue变量时不需要加变量名 在非vue事件中使用vue中变量时需要加变量名 正确 < ...
- 【bug记录】OS Lab4 踩坑记
OS Lab4 踩坑记 Lab4在之前Lab3的基础上,增加了系统调用,难度增加了很多.而且加上注释不详细,开玩笑的指导书,自己做起来困难较大.也遇到了大大小小的bug,调试了一整天. 本文记录笔者在 ...
随机推荐
- P1440 求m区间内的最小值
题目描述 一个含有n项的数列(n<=2000000),求出每一项前的m个数到它这个区间内的最小值.若前面的数不足m项则从第1个数开始,若前面没有数则输出0. 输入输出格式 输入格式: 第一行两个 ...
- 安装JPype时出现的 Unable to find vcvarsall.bat
解决方案,在网上找到的,mark一下,亲测有效 C:/Python31/Lib/distutils目录下的msvc9compiler.py中 修改MSVCCompiler函数:vc_env = que ...
- 微信官方UI库—WeUI
WeUI 为微信 Web 服务量身设计 概述 WeUI是一套同微信原生视觉体验一致的基础样式库,由微信官方设计团队为微信 Web 开发量身设计,可以令用户的使用感知更加统一.包含button.cell ...
- IOS 中使用token机制来验证用户的安全性
登录的业务逻辑{ http:是短连接. 服务器如何判断当前用户是否登录? // 1. 如果是即时通信类:长连接. // 如何保证服务器跟客户端保持长连接状态? // ...
- API设计指南(译)
API的设计在软件系统中的重要性不言而喻,在swift.org上看到一篇“API Design Guidelines”,虽然是就Swift而言,但对于其它语言也有不少可以借鉴的地方,在这里粗略翻译一二 ...
- Node.js——流的下载
https://cnodejs.org/topic/59d8f43b2543cb3368b1623e var request = require('request'); var fs = requir ...
- VS2008 ActiveX(ocx控件)的调试工具ActiveX Control Test Container安装说明
vs2008中的TSTCON( ActiveX Control Test Container )工具非自动安装,而是作为一个例程提供.所以应找到该例程,并编译: 如vs2008安装在默认路径则 1, ...
- JavaSE-24 多线程
学习要点 线程概述 Java中的多线程 线程状态 线程调度 线程同步 线程间通信 线程概述 1 进程 进程就是应用程序的执行实例. 进程特征: 动态性:动态产生,动态消亡.进程启动,系统为其分配资源 ...
- vue解决IOS10低版本白屏问题
一.方案一 在build文件的webpack.prod.conf.js文件添加以下代码 new UglifyJsPlugin({ uglifyOptions: { compress: { warnin ...
- idea拉出Output窗口和还原窗口
拉出:按住标题可以拖出 效果: 还原:点击restore layout