小工具      在线工具  汉语词典  css  js  c++  java

【Spring Cloud阿里巴巴】(5)Dubbo启动报错?重新连接时一直报错?你应该学会的是如何解决问题

Spring Cloud Alibaba 微服务实战,java,微服务,spring cloud,dubbo,启动报错 额外说明

收录于:40天前

CSDN成就一亿技术人

系列目录

【Spring Cloud阿里巴巴】(一)微服务介绍及Nacos注册中心实际实现
【Spring Cloud阿里巴巴】(二)微服务调用组件Feign原理+实战
【Spring Cloud阿里巴巴】(三)OpenFeign扩展点实践+详细源码讲解
【Spring Cloud阿里巴巴】(四)Dubbo框架介绍以及Dubbo与OpenAI的实际集成【文末附源码】



前言

继续上一篇文章,关于Dubbo,它真的很好用,而且真的很强大!不过,名人众多,偶尔也能听到各种关于Dubbo陷阱的传闻。

比如,消费者启动报错:Failed to check the status of the service xxx.没有提供该服务的提供商。 。 。

再比如,消费者启动成功后,一直与提供者重新连接,并报错:Fail to connect to HeaderExchangeClient。 。 。

你真的认为这是Dubbo的陷阱吗?

加一个小插曲,我想做一下调查:当遇到技术问题时你会怎么做?

  1. 我以前没见过。忽略它即可。直接网上搜索,用搜索方法~~~

    然后,网上就有各种各样的文章。运气好的话可以直接解决。如果你运气不好的话,你已经尝试了很多方法都没有效果......

  2. 我一次又一次向同事请教,感到很无助……

  3. 快速排查报错(运气好的话直接解决)。如果失败,则有针对性地查找信息。如果遇到困难,请向同事(或CSDN老板)寻求建议。

本文就以这两个Dubbo常见问题入手,带你进入如何通过源码分析解决问题 !一起拉开有趣的程序人生,Let’s go!

Dubbo避坑指南


一、启动报错

1. 两种场景

当消费者启动时,可能会遇到以下两种场景:

  • 没有可用的服务提供商,即注册中心没有注册 依赖的提供方
    例如:提供方正在部署中,或者提供方也是启动报错
  • 网络问题,导致消费方与提供方连接不上
    例如:Local环境与DEV环境的网不通,因为服务器上通常都是部署在Docker里.

不管怎样,你得先启动服务~~~

2. 报错信息

那么,消费方启动失败,会抛出 IllegalStateException,报错信息大致如下:

Error creating bean with name ‘xxxBean’: Injection of @DubboReference dependencies is failed; nested exception is java.lang.非法状态异常: Failed to check the status of the service xxx接口名称. No provider available for the service xxx接口名称 from the url xxx网址 to the consumer xxx本地主机 use dubbo version xxx版本

例如,我未启动提供者,重现的报错截图如下:
Dubbo启动报错 Failed to check the status of the service

3. 排查问题

搜索报错信息Failed to check the status of the service,可以快速定位到报错的源码,如下图:
Dubbo源码:Failed to check the status of the service

看到if判断条件shouldCheck()方法了吧? 从命名就可以看出来,这是判断是否应该检查,进去看看:

Dubbo shouldCheck()

只需几行代码,我想您就可以弄清楚:

:isCheck() 没有配置,默认为null

:由于① 为null,所以主要看getConsumer()

:如果① 和②均没配置,第3步默认设为true,即检查是否可用!

所以,对于我们来说,主要的配置点是getConsumer().isCheck(),

ConsumerConfig类的isCheck()方法

public Boolean isCheck() {
    return check;
}

ConsumerConfig类,从名子可以看出来:消费者配置类.

稍微找一找就可以找到,在@EnableDubbo注解上有一个@EnableDubboConfig注解,里面注释写着:

Dubbo源码:@EnableDubbo

再到注释对应的源码里验证一下,如果你从@EnableDubboConfig上的DubboConfigConfigurationRegistrar进去,可以看到DubboConfigConfiguration

Dubbo源码:DubboConfigConfigurationRegistrar

再跟进去,从这里就可以找到对应的源码:ConsumerConfig类绑定的配置前缀为dubbo.consumer,如下图:
Dubbo源码:DubboConfigConfiguration,ConsumerConfig

4. 补充说明

综上,配置dubbo.consumer.check = false 就代表消费方启动时不检查提供方是否可用!

  • 应用程序属性
dubbo.consumer.check = false

此处的附加说明如下:

Dubbo服务消费方在启动时,缺省会检查依赖的服务提供方是否可用,不可用时会抛出异常,阻止 Spring 初始化完成,以便上线时,能及早发现问题,默认 check=true

可以通过 check=false 关闭检查,比如:测试时,有些服务不关心,或者出现了循环依赖,必须有一方先启动。


二、一直重连报错

1. 两种场景

当通过check=false启动消费方后,还可能会遇到以下两种场景:

  • 网络问题,导致消费方与提供方连接不上(上面提到的第2点)
    例如:Local环境与DEV环境的网不通,因为服务器上通常都是部署在Docker里。
  • 获取到的是离线的提供方
    例如:消费方启动时,提供方也在重新部署,这时就有可能获取到刚下线的提供方.。
    大部分情况:等待一小会,会自动更新为新部署的提供方,但是偶尔也存在一直无法更新过来的情况。

如果你不关心错误报告的提供者,你真的不想看到不断重连的错误报告!

2. 报错信息

消费方启动成功,但与提供方连接失败,会一直报错并抛出 RemotingException,报错信息大致如下:

header.重新连接定时器任务 : [DUBBO] Fail to connect to HeaderExchangeClient [channel=org.apache.dubbo.remoting.transport.netty4.Netty客户端 [xxx -> /xxx:20880]], dubbo version: xxx版本, current host: xxx本地主机

org.apache.dubbo.remoting.远程处理异常: client(url: xxxURL) failed to connect to server /xxx:20880 client-side timeout 3000ms (elapsed: 3012ms) from netty client xxx using dubbo version xxx版本

例如,我这里本地环境中的消费者端DEV环境中的提供者,重现的报错截图如下:

Dubbo报错:Fail to connect to HeaderExchangeClient

3. 排查问题

全局或者直接到报错的ReconnectTimerTask类中搜索报错信息Fail to connect to,可以快速定位到报错的源码,如下:

Dubbo源码搜索:Fail to connect to

打印的e根据报错信息,可以确定是这里:

Dubbo源码:doConnect抛出RemotingException

ReconnectTimerTask,从名子就可以看出来:是重连定时任务,所以,如果想让它不报错,就需要看看:是否可以不启动这个定时器,这样自然就不会打印ERROR了,是这个逻辑吧?

OK,那我们得先找到启动定时器的地方,怎么找?

对,先查找一下ReconnectTimerTask的类的引用,很快就定位到了HeaderExchangeClient.startReconnectTask(URL url)方法,看名子就知道:启动重连任务

Dubbo源码:定位HeaderExchangeClient.startReconnectTask

OK,到这我不说你应该也发现了,这里有个if判断条件shouldReconnect(url)方法,和第一个问题的shouldCheck都是统一命名规则,想都不用想,可以肯定就在这里控制它!

我们看一下,代码就一行,url.getParameter内部是从Map中查找reconnect,找不到默认会设为true:

String RECONNECT_KEY = "reconnect";
private boolean shouldReconnect(URL url) {
    
    return url.getParameter(Constants.RECONNECT_KEY, true);
}

那么问题来了, reconnect参数在哪配置?

如果我们在这里查找参考,链接有点深,所以为了看得更清楚,我们可以设置一个断点并查看调用堆栈。

这样,一下就找到了入口:ReferenceConfig.get方法,这里代码更少,主要就是调用init()方法。

Dubbo源码调试,找到ReferenceConfig.get入口

转到init()方法的313行,传入的正是一个map,如下图,调试发现里面竟然有check=false,所以猜测还是与ConsumerConfig(消费者配置类)有关,方法里再向上找一找,还真找到了ConsumerConfig类的对象consumer,从名子appendParameters就知道它是往map里追加consumer的配置!所以就这样配置上了!

Dubbo源码:ReferenceConfig.init中分析map

所以我们在dubbo.consumer下面配一下试试,

  • 应用程序属性
dubbo.consumer.reconnect = false

不出所料,生效了!如下图
Dubbo源码:reconnect配置生效

4. 补充说明

综上,配置dubbo.consumer.reconnect = false 就代表消费方没有重新连接提供方!

实际上,这里有一个机制,就是Dubbo的重连机制,也是为了能及早发现问题,所以建议生产环境不要修改此配置!

而这个配置多用于开发环境,用于忽略不关心的服务!

那么,对于关心的服务,需要调用的话,怎么做?

可以考虑以下两种方法

  • 做法1. 对网络不通的环境,进行服务隔离

可以配置Nacos服务发现组隔离服务注册,例如:

spring.cloud.nacos.discovery.group=XXX_GROUP

这样就可以在本地环境中只调整本地服务,在DEV环境中只调整DEV服务。您只需配置相同的组名即可!

  • 做法2. 不做服务隔离,在实际调用失败后,做容错能力

因为调用环节可能比较复杂,有时环境隔离的成本太高,那么可以将其转换为HTTP请求,向Nginx或Gateway发起HTTP调用。这也是针对上述两种场景下RPC调用异常的掩盖解决方案!


总结

有了Java的开源框架,我们有时候不需要太深入的去遵循,但是我们仍然可以很快的解决一些问题!

  • 搜索错误文本并定位源代码位置
  • 通过搜索引用和断点找到入口点,分析导致错误发生的原因。
  • 通过其名称或注释了解方法的意图,并通过主流程快速找到解决问题的关键点。

最后

虽然框架源码不断变化,但是方法是一样的,套路都是一样的。更值得学习的是解决问题的方法,更重要的是养成独立解决问题的习惯。我相信你能做到!

如果你学会了如何解决问题,以后你就会非常独立,你的老板和同事也会看到你对事情的把握很好。你甚至可能成为疑难杂症专家!即使遇到问题你去问大师,他也会觉得你的问题水平不错,并且会以帮你解决问题而错过为荣!

所以,遇到问题并不是坏事。多解决这些问题会让你更有经验,更熟悉饮食的框架。这些是你的资产,也可以包含在你的简历中以供面试。官员更喜欢你。不过友情提醒,控制好规模,在项目过程中遇到问题时不要卡在问题上,不要陷入细节而影响项目进度!

img

那么对于Dubbo RPC调用异常转移到HTTP调用,你知道怎么实现吗?这也是我计划将在在本栏下方分享的内容,如果感觉不错,欢迎订阅本专栏,后面还有更多的【Spring Cloud 阿里巴巴】实用知识陆续放出。

关注我 天罡格 分享更多干货: https://blog.csdn.net/scm_2008
大家的「关注❤️+点赞-+收藏⭐」就是我创作的最大动力!谢谢大家的支持,我们下文见!

. . .

相关推荐

额外说明

sql server导出表结构

网上找到一个脚本还不错,小小的修改就满足了我的要求,执行完SQL脚本。 在结果就能看到数据库所有表的结构,这个时候只要全选,然后右击出来属性框,选择将结果另存为,这个时候您只要选择导出CSV,然后新建一个Excel表格,在菜单栏选择数据,再选择自文本,后

额外说明

【JAVA-Day41】Date 在java中的使用

Date 在java中的使用 Java常用类 Date 解析,高效处理日期问题 引言 一、什么是Date类 二、Date类的方法(JDK8) 获取日期的毫秒表示 - `getTime()` 比较日期 - `before(Date when)` 和 `af

额外说明

uniapp实战——项目功能介绍

QQ 1274510382 Wechat JNZ_aming 商业联盟 QQ群538250800 技术搞事 QQ群599020441 解决方案 QQ群152889761 加入我们 QQ群649347320 共享学习 QQ群674240731 纪年科技am

额外说明

移动电商——Flutter-商品列表数据模型建立

QQ 1274510382 Wechat JNZ_aming 商业联盟 QQ群538250800 技术搞事 QQ群599020441 解决方案 QQ群152889761 加入我们 QQ群649347320 共享学习 QQ群674240731 纪年科技am

额外说明

Server2129

需要环境请私信博主!!!  服务器场景:Server2129(关闭链接) 服务器用户名:未知 服务器密码:未知 服务器场景操作系统:Windows

额外说明

mathematica 11.2 keygen

激活码在线产生地址

额外说明

g++ 编译过程体会与命令行参数argc,argv[]详解

argc, *argv[] 参数介绍 main(int argc,char *argv[ ]) argc为整数, 代表参数的个数。 argv为指针数组,里面的元素个数是 argc 个,(可理解为:char **argv or: char *argv[]

额外说明

前端代码接入单元测试一

本篇是前端单元测试的第一篇文章,从基础讲解然后到前端的react单元测试及node的单元测试 一、单元测试发展 1、为什么要有单元测试 软件测试是一种实际输出与预期输出之间的审核或者比较过程 测试可以尽早发现BUG 测试可以提高代码质量 测试可以让我们自

额外说明

wordpress创建_如何使用StoryBuilder在WordPress中创建精美的长格式内容

由 WordPress 创建 最近,我们的一位读者问是否可以在 WordPress 中创建漂亮的长格式内容?事实证明,带有讲故事元素的长篇内容比纯文本和图像更有吸引力。在本文中,我们将向您展示如何使用 StoryBuilder 在 WordPress 中

额外说明

Springboot集成Sentinel实战

1.哨兵简介 官方介绍: https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D  随着微服务越来越流行,服务与服务之间的稳定性变得越来越重要。 Sentinel以流量为切入点,从流量控制、

ads via 小工具