同时使用注解和 xml 的方式引用 dubbo 服务产生的异常问题排查实战

news2024/11/16 23:49:09

文章目录

      • 一、现象
      • 二、问题排查
      • 三、结论
      • 四、解决方案

一、现象

使用 nacos 作注册中心的线上 dubbo 消费端应用每隔 1 分钟就会抛出以下异常(为使描述简单化,文章中使用本地 demo 来复现),该异常表示无法连接到 172.17.0.1:20881 这台提供端

21:11:49.843 [dubbo-client-idleCheck-thread-1] ERROR org.apache.dubbo.remoting.exchange.support.header.ReconnectTimerTask.doTask(51) -  [DUBBO] Fail to connect to HeaderExchangeClient [channel=org.apache.dubbo.remoting.transport.netty4.NettyClient [172.17.0.1:0 -> /172.17.0.1:20881]], dubbo version: 2.7.3, current host: 172.17.0.1
org.apache.dubbo.remoting.RemotingException: client(url: dubbo://172.17.0.1:20881/com.example.dubbo.HelloService?anyhost=true&application=dubbo-consumer-app&bean.name=com.example.dubbo.HelloService&category=providers&check=false&codec=dubbo&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&heartbeat=60000&interface=com.example.dubbo.HelloService&lazy=false&methods=sayHello&path=com.example.dubbo.HelloService&pid=56029&protocol=dubbo&register=true&register.ip=172.17.0.1&release=2.7.3&remote.application=dubbo-provider-app&server=netty4&side=consumer&sticky=false&timestamp=1683113373687) failed to connect to server /172.17.0.1:20881, error message is:拒绝连接: /172.17.0.1:20881
	at org.apache.dubbo.remoting.transport.netty4.NettyClient.doConnect(NettyClient.java:166)
	at org.apache.dubbo.remoting.transport.AbstractClient.connect(AbstractClient.java:190)
	at org.apache.dubbo.remoting.transport.AbstractClient.reconnect(AbstractClient.java:246)
	at org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeClient.reconnect(HeaderExchangeClient.java:155)
	at org.apache.dubbo.remoting.exchange.support.header.ReconnectTimerTask.doTask(ReconnectTimerTask.java:49)
	at org.apache.dubbo.remoting.exchange.support.header.AbstractTimerTask.run(AbstractTimerTask.java:87)
	at org.apache.dubbo.common.timer.HashedWheelTimer$HashedWheelTimeout.expire(HashedWheelTimer.java:648)
	at org.apache.dubbo.common.timer.HashedWheelTimer$HashedWheelBucket.expireTimeouts(HashedWheelTimer.java:727)
	at org.apache.dubbo.common.timer.HashedWheelTimer$Worker.run(HashedWheelTimer.java:449)
	at java.lang.Thread.run(Thread.java:748)
Caused by: io.netty.channel.AbstractChannel$AnnotatedConnectException: 拒绝连接: /172.17.0.1:20881
	at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)
	at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:717)
	at io.netty.channel.socket.nio.NioSocketChannel.doFinishConnect(NioSocketChannel.java:325)
	at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:340)
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:635)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:582)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:499)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:461)
	at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	... 1 more
Caused by: java.net.ConnectException: 拒绝连接
	... 11 more

二、问题排查

经过确认,172.17.0.1:20881 这台提供端确实已经下线,所以才会无法连接。

通过查询 dubbo 源码得知,ReconnectTimerTask 是一个定时任务,其实例被 DubboInvoker 实例持有,当 DubboInvoker 对应的消费端服务与对端的提供端服务断开连接时,该定时任务就会定时重连提供端。正常情况下不会出现这种异常,因为提供端下线以后,会通过注册中心通知到消费端,消费端对应的 DubboInvoker 实例会被销毁,从而重连定时任务也会被销毁。

找到出问题的 HelloService 在应用中的使用方式,发现既有通过 @Reference 注解的方式使用,又有通过 xml 配置的方式使用。首先,将 arthas 连接到出问题的消费端应用,然后执行以下命令

ognl '#context=@org.apache.dubbo.config.spring.extension.SpringExtensionFactory@CONTEXTS.iterator.next, #context.getBean("helloService").handler.invoker.directory.urlInvokerMap'

得到结果为

在这里插入图片描述

发现 HelloService 服务的 RegistryDirectory 实例中确实还存在已经下线的提供端,说明提供端下线后该消费端没有感知到

接着,使用 arthas 监控看看消费端的服务监听 notify 方法是否生效,运行以下命令

watch org.apache.dubbo.registry.support.FailbackRegistry notify params

然后,将 20880 那台服务提供端也下线,看看 watch 命令的输出,如下所示

在这里插入图片描述

说明服务下线通知功能是正常的,不过这里的 RegistryDirectory 实例和上面使用 ognl 表达式查询的 RegistryDirectory 实例不是同一个,使用 ognl 表达式查询的实例如下

在这里插入图片描述

说明 HelloService 服务被 refer 了两次,也就是生成了两个服务引用,但是只有一个引用的服务监听生效。

三、结论

联系到 HelloService 在应用中有注解和 xml 两种引用方式,调试一遍服务引用的创建过程,发现在 NacosRegistry 中有这么一段服务订阅代码

在这里插入图片描述

这段代码的意思是,当相同的服务引用被创建了两次,只有第一次创建的引用会订阅服务。所以通过注解和 xml 两种方式创建 HelloService 服务引用时,会导致其中一个引用不会订阅服务变更,导致无法感知提供端下线,就会出现不断重连提供端的现象。

四、解决方案

应用中应当禁止同时使用注解和 xml 的方式来引用 dubbo 服务。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/487040.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JavaWeb( 二 ) URL

1.4.URL统一资源定位符 URL代表Uniform Resource Locator 统一资源定位符,也叫 URL地址 。是用于标识和定位Web上资源的地址,通常用于在Web浏览器中访问网站和文件。 URL由若干部分组成,scheme:// host : port / path 例如: htt…

Contest3111 - 计科2101~2104算法设计与分析上机作业07

问题 A: 有重复元素的排列问题 题目描述 设R{ r 1 , r 2 , …, r n }是要进行排列的n个元素。其中元素r 1 , r 2 , …, r n 可能相同。试设计一个算法, 列出R的所有不同排列。给定n 以及待排列的n 个元素。计算出这n 个元素的所有不同排列。 输入 第1 行是元素个…

android四大组件之一-Activity实现原理分析

前言: 这篇文章是我花费时间最久的一篇文章,整整的两个月。整个流程繁琐是一个方面的原因,另外一个原因是我想尽可能的把整个流程的逻辑尽可能详细的一一描述出来,以及结合到我们项目中遇到的一些问题来进行解释,毕竟…

【五一创作】VS+Qt主界面内嵌自定义控件的四种方法以及不同自定义控件数据交互

前言 在Qt界面开发过程中,一个主界面或者主窗口看成是各个控件排列组合后的集合,对于一些项目而言,有些常用的控件可以封装成自己想要的控件样式并且复用,比如说,log显示控件,图像/视频显示控件等&#xf…

【ros2】ros melodic迁移到ros2 dashing过程中碰到的问题及解决方法

序言 总结踩坑经历,以利他人 1. error: forming pointer to reference type … & 报错原因: ros2回调函数的参数不能是引用形式 &,需要去除& 解决方法: 如果是指针引用,直接去除引用 void Callback(con…

【Java开发】Spring Cloud 11:Gateway 配置 ssl 证书(https、http、域名访问)

最近研究给微服务项目配置 ssl 证书,如此才可以对接微信小程序(需要使用 https 请求)。传统单体项目来说,首先往项目中添加证书文件,然后在配置文件中配置 ssl 证书路径、密码等相关信息;那么微服务这么多项…

机器学习强基计划8-5:图解局部线性嵌入LLE算法(附Python实现)

目录 0 写在前面1 流形学习2 局部线性嵌入算法2.1 什么是局部线性嵌入?2.2 算法原理推导 3 Python实现3.1 算法流程3.2 核心代码3.3 可视化 0 写在前面 机器学习强基计划聚焦深度和广度,加深对机器学习模型的理解与应用。“深”在详细推导算法模型背后的…

基于学生成绩管理系统(附源代码及数据库)

基于Ecplise,jsp的学生成绩管理系统 目录 登录页面 系统主页 管理员账号管理 学生查询 课程管理 成绩管理 后台数据库 源代码下载(含数据库) 毕设项目专栏 分为以下四大板块: 系统用户管理: 包含管理员账号管理&#…

【一起撸个DL框架】5 实现:自适应线性单元

CSDN个人主页:清风莫追欢迎关注本专栏:《一起撸个DL框架》GitHub获取源码:https://github.com/flying-forever/OurDL 文章目录 5 实现:自适应线性单元🍇1 简介2 损失函数2.1 梯度下降法2.2 补充 3 整理项目结构4 损失函…

第二十七章 Unity碰撞体Collision(下)

本章节我们继续研究碰撞体,并且探索一下碰撞体与刚体之间的联系。我们回到之前的工程,然后给我们的紫色球体Sphere1也添加一个刚体组件。如下所示 此时,两个球体都具备了碰撞体和刚体组件。接下来,我们Play运行查看效果 我们发现&…

第二十六章 Unity碰撞体Collision(上)

在游戏世界中,游戏物体之间的交互都是通过“碰撞接触”来进行交互的。例如,攻击怪物则是主角与怪物的碰撞,触发机关则是主角与机关的碰撞。在DirectX课程中,我们也大致介绍过有关碰撞检测的内容。游戏世界中的3D模型的形状是非常复…

浅谈区块链1.0-比特币

1. 比特币解决的问题 高度自治:国际经济危机无国界贸易:不同国家进行的贸易或者不同平台进行贸易 不可窜改:例如银行交易可能会被窜改数据 隐私安全:传统汇款方式会暴露你的个人信息,一旦数据库被别人入侵&#xff0c…

android基础知识复习

架构: 应用框架层(Java API Framework)所提供的主要组件: 名称功能描述Activity Manager(活动管理器)管理各个应用程序生命周期,以及常用的导航回退功能Location Manager(位置管理器…

SpringBoot整合Mybatis-plus实现多级评论

在本文中,我们将介绍如何使用SpringBoot整合Mybatis-plus实现多级评论功能。同时,本文还将提供数据库的设计和详细的后端代码,前端界面使用Vue2。 数据库设计 本文的多级评论功能将采用MySQL数据库实现,下面是数据库的设计&…

Boonz-KeygenMe#1(★★★)

运行程序 错误: 查壳 没有壳,是汇编写的程序 载入OD 前面是在读取输入内容,到这里开始做计算了 分析 首先遍历了用户名,计算结果保存在EBX,在存放到 0x40E0F8 对EBX中的值再次计算,最后结果保存到 …

JavaFX: Java音乐播放读取歌词

JavaFX: Java音乐播放读取歌词 1、lrc歌词文件2、解析lrc歌词2.1 读取每行歌词2.2 解析歌词时间标签Time-tag2.3 解析歌词标识标签ID-tags2.4 创建对象包含歌词相关信息 3、播放显示歌词** 相关文献 JavaFX: Java音乐播放 1、lrc歌词文件 lrc歌词文件的扩展名 1、标准格式&a…

图像处理:Retinex算法

目录 前言 概念介绍 Retinex算法理论 单尺度Retinex(SSR) 多尺度Retinex(MSR) 多尺度自适应增益Retinex(MSRCR) Opencv实现Retinex算法 SSR算法 MCR算法 MSRCR算法 效果展示 总结 参考文章 前…

基频建模方法总结

基频F0建模方法 语音合成领域需要对基频进行建模,具体到文语转换TTS、语音转换VC、情感语音转换EVC领域等。 语音合成F0 包括文语转换,情感语音转换 TTEF:text-to-emotional-features synthesis EVC:emotional voice conversio…

这些你熟知的 app 和服务,都用上了人工智能

从微软在 Microsoft 365 服务中全面整合 GPT-4 能力 ,让 PPT、Word 文档、Excel 表格的制作变成了「一句话的事」,到 Adobe 刚刚发布 Adobe Firefly模型集合,让图形设计、字体风格、视频渲染乃至 3D 建模的门槛显著降低——你我熟知的那些工…

idea的快捷键

一.idea的快捷键: 递进选择&#xff1a;ctrl w复制行&#xff1a;ctrl d删除行&#xff1a;ctrl y大小写切换&#xff1a;ctrl shift u展开/折叠&#xff1a;ctrl shift 减号/加号向前/向后&#xff1a;ctrl <— / —>Live Template(例如 输入psvm会自动打出mai…