当前位置: 首页 > 编程日记 > 正文

Dubbo 2.7.1 踩坑记

Dubbo 2.7 版本增加新特性,新系统开始使用 Dubbo 2.7.1 尝鲜新功能。使用过程中不慎踩到这个版本的 Bug。

系统架构

Spring Boot 2.14-Release + Dubbo 2.7.1

现象

Dubbo 服务者启动成功,正常提供服务,消费者调用偶现失败的情况。错误如下图:

1558321992914-2ef5dbd0-806c-47d9-88aa-1ad24920b1b6.png#align=left&display=inline&height=714&originHeight=714&originWidth=1549&size=0&status=done&width=1549

可以看出,主要原因为 cause: message can not send, because channel is closed。 但是检查提供者,却发现服务进程正常。

登陆 Dubbo admin 查看提供者服务,发现这个服务存在两个节点。

1558321992969-f7ec7343-3dfc-4c35-a794-84edb908d748.png#align=left&display=inline&height=545&originHeight=545&originWidth=1025&size=0&status=done&width=1025

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。

1558321992946-4f88d227-7240-422a-93e8-0bf95ff69ec1.png#align=left&display=inline&height=192&originHeight=192&originWidth=767&size=0&status=done&width=767

后续 PR 中已修复该问题 Fix issue 3785,修复代码将 dynamic 默认设置成 true。但是截止 20190515 该版本暂未发布。

源码分析

知道问题原因,这里我们从源码分析一下,为什么 dynamic 设置成 false 会导致该问题。

注:下面分析的是 Dubbo 2.7.1 的源码
下面我们使用 Dubbo xml 配置相关。

在 xml 配置中,可以在以下两个地方设置 dynamic 属性。

1558321993073-3ceca2a3-40fd-49ce-96bd-3c9574ae065b.png#align=left&display=inline&height=820&originHeight=820&originWidth=1400&size=0&status=done&width=1400

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

1558321992946-4afc4fc2-77e8-4dcf-bf4c-75adb2b97df3.png#align=left&display=inline&height=667&originHeight=667&originWidth=1529&size=0&status=done&width=1529

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

1558321993006-20acb303-fee8-4d2a-b161-31920cacc700.png#align=left&display=inline&height=229&originHeight=229&originWidth=704&size=0&status=done&width=704

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

1558321993029-4e661481-d557-41d6-a311-10f373002ef1.png#align=left&display=inline&height=171&originHeight=171&originWidth=1250&size=0&status=done&width=1250

可以看到该字段默认值为 false

接着查看 Dubbo 服务导出过程,位于 ServiceBean#export,略过其他代码,我们直接跳到关键 ServiceConfig#doExportUrlsFor1Protocol

1558321993046-1ed4b203-ed23-4f90-92fe-71e784a4ea85.png#align=left&display=inline&height=357&originHeight=357&originWidth=1133&size=0&status=done&width=1133

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

1558321993050-358b0a09-c895-49f1-94de-00ec97c25787.png#align=left&display=inline&height=485&originHeight=485&originWidth=624&size=0&status=done&width=624

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

接着我们跳到后面:

1558321993054-a18c4fbf-c998-4685-a8da-a45c011a5413.png#align=left&display=inline&height=231&originHeight=231&originWidth=1159&size=0&status=done&width=1159

在这里会将上面得到 map 组装到 URL 对象中,然后再注册到注册中心。。

由于注册中心使用的是 ZooKeeper,所以这里将会使用 ZookeeperRegistry 实现类。

1558321993020-fa3f1b4c-d5cc-4566-acb8-35e8c2bd14f4.png#align=left&display=inline&height=196&originHeight=196&originWidth=1292&size=0&status=done&width=1292

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

1558321993071-4b971def-4092-4ad2-891a-a5eb33d04f02.png#align=left&display=inline&height=369&originHeight=369&originWidth=765&size=0&status=done&width=765

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

查看此时的 parameters 对象。

1558321993077-75de1713-0ae4-4fe5-bcf4-45ae93d57de9.png#align=left&display=inline&height=485&originHeight=485&originWidth=624&size=0&status=done&width=624

url.getParameter(Constants.DYNAMIC_KEY, true) 返回为 false。

然后分析 zkClient#create 方法,

1558321993022-3ed0dc3c-f43b-4191-a268-77d11056e84d.png#align=left&display=inline&height=438&originHeight=438&originWidth=863&size=0&status=done&width=863

由于 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 发布以后,再使用。

转载于:https://www.cnblogs.com/goodAndyxublog/p/10878186.html

相关文章:

经典算法研究系列:二、Dijkstra 算法初探

经典算法研究系列:二、Dijkstra 算法初探 July 二零一一年一月 本文主要参考:算法导论 第二版、维基百科。 写的不好之处,还望见谅。本经典算法研究系列文章,永久勘误,永久更新、永久维护。 July、二零一一年二月…

[Python Study Notes] Python的安装

Windows: 1.下载安装包: 转到Python官网https://www.python.org/downloads/ ,下载最新版本的Python。 2.安装 安装到自定义的安装路径下。 3.配置环境变量 安装完成后--》【右键快捷方式】--》【复制python路径】,例如&#xff1…

swing 实现电影选座系统

该系统使用swing数据库 实现一个电影选座系统,相关系统的截图如下 使用三层架构实现电影购票系统,分用户和管理员,用户功能:展示电影,查找电影(模糊查询),查看电影详情,查找场次,购买影票&…

JS动态加载JS

1、直接document.write <script language"javascript"> document.write("<script srctest.js><\/script>"); </script> 2、动态改变已有script的src属性 <script src id"s1"></script> <script lang…

PAT乙级1037

1037 在霍格沃茨找零钱 (20 分)如果你是哈利波特迷&#xff0c;你会知道魔法世界有它自己的货币系统 —— 就如海格告诉哈利的&#xff1a;“十七个银西可(Sickle)兑一个加隆(Galleon)&#xff0c;二十九个纳特(Knut)兑一个西可&#xff0c;很容易。”现在&#xff0c;给定哈利…

SAD和SATD的区别[摘]

Q:如果不用率失真最优化&#xff0c;为什么选择SATD&#xff0b;deltar&#xff08;mv&#xff0c;mode&#xff09;作为模式选择的依据&#xff1f;为什么运动估计中&#xff0c;整象素搜索用SAD&#xff0c;而亚象素用SATD&#xff1f;为什么帧内模式选择要用SATD&#xff1f…

照片换色 使用Python 或者 java

记录使用第三方api 给照片换底色&#xff0c;智能抠图。 1、第三方接口地址 https://www.remove.bg/api 2、抠图效果 3、使用python 实现的代码 在网页换色是不需要进行注册的&#xff0c;如果自己开发 需要注册账号 &#xff0c;得到调取api的口令 import requests impor…

WEB安全,SQL注入漏洞的加固代码汇总

该修复任务专用于处理以下安全性问题&#xff1a;[1] SQL 盲注[2] SQL 注入[3] XPath 注入[4] 发现数据库错误模式[5] 跨站点脚本编制[6] 使用 SQL 注入的认证旁路[7] HTTP 响应分割[8] 链接注入&#xff08;便于跨站请求伪造&#xff09;详细信息若干问题的补救方法在于对用户…

mui ios中form表单中点击输入框头部导航栏被推起及ios中form表单中同时存在日期选择及输入框时,日历选择页面错乱bug...

一、ios header导航栏被推起解决方法 1 设置弹出软键盘时自动改变webview的高度 plus.webview.currentWebview().setStyle({ softinputMode: "adjustResize" // 弹出软键盘时自动改变webview的高度 }); 2 增加样式 html, body { height: 100%; margin: 0px; …

qt试用1(Eclipse+cdt+Qt)

下载eclipse-cpp-helios-SR1-win32.zip下载Qt下载qt-eclipse-integration-win32-1.6.1.exe写一个启动eclipse的batch文件C:\program\eclipse-cpp-helios-SR1-win32\eclipse\cdt.batset path%path%;C:\Qt\2010.05\mingw\binset LIBRARY_PATHC:\Qt\2010.05\mingw\libset C_INCLUD…

Solr 中遇到的问题

1、问题1 &#xff1a;whose UTF8 encoding is longer than the max length 32766 Error from server at http://localhost:8983/solr/newcore: Exception writing document id 995 to the index; possible analysis error: Document contains at least one immense term in f…

【推荐】Flex+asp.net上传文件

前台Flex文件&#xff1a;UploadSample.mxml&#xff0c;其代码如下所示&#xff1a; 1 <?xml version"1.0" encoding"utf-8"?>2 <mx:Application xmlns:mx"http://www.adobe.com/2006/mxml"layout"absolute">3 <mx:…

Centos查找命令清单

查找目录&#xff1a;find /&#xff08;查找范围&#xff09; -name 查找关键字 -type d查找文件&#xff1a;find /&#xff08;查找范围&#xff09; -name 查找关键字 -print 如果需要更进一步的了解&#xff0c;可以参看Linux的命令详解。 这里摘抄如下&#xff1a; find …

docker 安装使用 solr

目录 1、安装solr 7.5 2、启动solr服务 2.1 创建一个solr库 3、配置IK分词器 4、docker 配置solr登录密码 1、安装solr 7.5 docker solr 官网&#xff1a;https://hub.docker.com/_/solr/ docker pull solr:7.5.0 2、启动solr服务 docker run --name my_solr -d -p 898…

2010中国城市GDP排名

1、上海市 14900.93亿元 8.2&#xff05; 上海 2、北京市 11865.9亿元 10.1% 北京 3、广州市 9118.6亿元 11% 广东1 4、深圳市 8245亿元 10.5% 广东2 5、天津市 7500亿元 16.5% 天津 6、苏州市 7400亿元 11% 江苏1 7、重庆市 5856亿元 14.9% 重庆 8、杭州市 5098.66亿元 10% 浙…

基于wsimport生成代码的客户端

概述 wsimport是jdk自带的命令&#xff0c;可以根据wsdl文档生成客户端中间代码&#xff0c;基于生成的代码编写客户端&#xff0c;可以省很多麻烦。wsimport命令 wsimport的用法 wsimport [options] <WSDL_URI>比较常用的[options]有&#xff1a;1. -d <directory>…

C# Trim 的使用

C# 移除字符 /// <summary> /// 删除指定字符 /// </summary> /// <returns>返回经过修饰的字符串</returns> private string DelChar() { string mess " Test Program "; // 测试字符 if (mess ! string.Empty) …

CSS截取字符串,兼容浏览器

今天在经典论坛看到有同学问到CSS截取字符多余省略号代替的求助且要兼容FF... 这个的确是个比较头痛的问题&#xff0c;现在我在的公司都是程序截取显示省略符的。兼容是没问题&#xff0c;但在中文和数学或字母混排时&#xff0c;就会有点小小的视觉缺陷。在程序截取中&#x…

SQL Server Alwayson 主从数据库账号同步

我们建立了Alwayson后&#xff0c;辅助副本下的数据库是没有相应的账号的&#xff0c;怎么样进行账号的同步呢&#xff1f;怎么在不知道密码的情况下&#xff0c;进行账号的同步设置。 我们可以通过SP--sp_help_revlogin 来实现&#xff0c;此存储过程在主副本上创建了&#xf…

Python 使用 Flask框架记录

Python 使用 Flask框架记录 1、安装Flask ​ Flask依赖两个外部库&#xff0c;Werkzeug和Jinja2&#xff0c;Werkzeug是一个WSGI(服务器网关接口)。Jinja2时负责渲染模板。在安装Flask之前需要安装这俩个外部库&#xff0c;最简单的安装方式是使用Vritualenv创建虚拟环境。 …

java8学习之Lambda表达式深入与流初步

Lambda表达式深入&#xff1a; 在上一次【http://www.cnblogs.com/webor2006/p/8135873.html】中介绍Lambda表达式的作用时&#xff0c;其中说到这点&#xff1a; 如标红处所说&#xff0c;既然Lambda表达式是一个对象&#xff0c;而且必须依附于一类特别的对象类型叫函数式接口…

Javascript与正则表达式个人总结与收录--高级篇

一、正则表达式中的量词 贪婪量词&#xff1a; 先看整个字符串是不是一个匹配。如果没有发现匹配&#xff0c;它去掉最后字符串中的最后一个字符&#xff0c;并再次尝试。如果还是没有发现匹配&#xff0c;那么再次去掉最后一个字符串&#xff0c;这个过程会一直重复直到发现一…

第二十五章 面向对象------封装、内置函数、反射、动态导入

1、封装 什么是封装&#xff1f; 1.对外部隐藏内部的属性&#xff0c;以及实现细节&#xff0c;给外部提供使用的接口 注意&#xff1a;封装有隐藏的意思&#xff0c;但不是单纯的隐藏 学习封装的目的&#xff1a;就是为了能够限制外界对内部数据的访问 python中属性的权限分为…

STL vector list deque区别与实现

1 vector 向量 相当于一个数组 在内存中分配一块连续的内存空间进行存储。支持不指定vector大小的存储。STL内部实现时&#xff0c;首先分配一个非常大的内存空间预备进行存储&#xff0c;即capacituy&#xff08;&#xff09;函数返回的大小&#xff0c;当超过此分配的空间…

pigeon 介绍

https://github.com/dianping/pigeon Pigeon开发指南 Pigeon是一个分布式服务通信框架&#xff08;RPC&#xff09;&#xff0c;在美团点评内部广泛使用&#xff0c;是美团点评最基础的底层框架之一。 主要特色 除了支持spring schema等配置方式&#xff0c;也支持代码annotati…

docker 安装使用 mysql

1、下载mysql镜像 docker pull mysql:5.7 2、运行mysql docker run --name my_mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORDXYBB_1314 -d mysql:5.7 参考&#xff1a; https://blog.csdn.net/jiangyu1013/article/details/79958410 https://www.cnblogs.com/limingxie/p/…

国内第一部IT治理综合图书问世

国内第一部全面阐述企业IT治理理念与实践的图书《中国企业的IT治理之道》于2010年3月由清华大学出版社正式出版发行。对国内的企业来说&#xff0c;IT治理并不是一个陌生的词汇。对于什么是IT治理&#xff1f;什么样的治理才是最优的&#xff1f;如何构建最适合企业的IT治理机构…

oracle终止用户会话

1.创建两个测试用户进行实验 执行命令如下&#xff1a; create user test1 identified by 1; create user test2 identified by 1; grant dba to test1; grant dba to test2; 如下图&#xff0c;我创建了两个用户,并授予两个用户dba角色。 2&#xff0c;windows下使用cmd连接or…

正试图在 os 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码......

当我在窗体初始化的时候&#xff0c;调用了一个外部的dill时&#xff0c;它就不知什么原因的 抛出一个“正试图在 os 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码”的异常,程序就卡掉了,在网上查了查&#xff0c;相关说明如下:.NET2.0中增加…

Nginx在windows下常用命令

cmd 进入Nginx解压目录 执行以下命令 start nginx : 启动nginx服务 nginx -s reload &#xff1a;修改配置后重新加载生效 nginx -s reopen &#xff1a;重新打开日志文件nginx -t -c /path/to/nginx.conf 测试nginx配置文件是否正确--------------------- 验证配置是否正确: n…