What?一个 Dubbo 服务启动要两个小时!

5d1e14ea0052047268.jpg

前言

前几天在测试环境碰到一个非常奇怪的与 dubbo 相关的问题,事后我在网上搜索了一圈并没有发现类似的帖子或文章,于是便有了这篇。

希望对还未碰到或正在碰到的朋友有所帮助。

现象

现象是这样的,有一天测试在测试环境重新部署一个 dubbo 应用的时候发现应用“启动不起来”

但过几个小时候之后又能自己慢慢恢复,并能够对外提供 dubbo 服务。

但其实经过我后续排查发现刚开始其实并不是启动不起来,而是启动速度非常缓慢,所以当应用长时间启动后才会对外提供服务。

5d1e14eb2d3b613329.jpg

而这个速度慢到居然要花费 2 个小时

导致的一个结果是测试完全不敢在测试环境发版验证了,每验证一个功能修复一个 bug 就得等上两个小时,这谁受得了?。

而且经过多次观察,确实每次都是花费两小时左右应用才能启动起来。

尝试解决

最后测试顶不住了,只能让我这个“事故报告撰写专家”来看看。

当我得知这个问题的现象时其实完全没当一回事:

都不用想,这不就是主线程阻塞了嘛,先看看是否在初始化的时候数据库、Zookeeper 之类的连不上导致阻塞了-------来之多次事故处理的经验告诉我。

于是我把这事打回给测试让他先找运维排查下,不到万不得已不要影响我 Touch fish?。

第二天一早看到测试同学的微信头像跳动时我都已经准备接受又一句 “膜拜大佬?” 的回复时,却收到 “网络一切正常,没人动过,再不解决就要罢工了?”。

好吧,忽悠不过去了。

首先这类问题的排查方向应该不会错,就是主线程阻塞了,至于是啥导致的阻塞就不能像之前那样瞎猜了。

我将应用重启后用 jstack pid 将线程快照打印到终端,直接拉到最后看看 main 线程到底在干啥。

前几次的快照都是很正常:

加载 Spring ---->连接 Zookeeper ---> 连接 Redis,都是依次执行下来没有阻塞。

隔了一段后应用确实还没起来,我再次 jstack 后得到如下信息:

5d1e14ec2185426171.jpg

翻源码

我一直等了十几分钟再多次 jstack 得到的快照得到的信息都是一样的。

5d1e14ec2185426171.jpg

如图所示可见主线程是卡在了 dubbo 的某个方法 ServiceConfig.java 的 303 行中。

于是我找到此处的源码:

5d1e14ec68e8259933.jpg

简单来说这里的逻辑就是要获取本机的 IP 将其注册到 Zookeeper 中用于其他服务调用。

5d1e14eca624d69950.jpg

再往下跟就如堆栈中一样是卡在了 Inet4AddressImpl.getLocalHostName 处。

但这是一个 native 方法,我们应用也根本干涉不了,最终的现象就是调用这个本地方法非常耗时。

于是这问题貌似也阻塞在这儿了,没有太多办法。

最终解决

既然这是一个 native 方法,那说明和应用本身没有啥关系(确实也是这样,这个问题是突然间出现的。)

那是否是服务器本身的问题呢,想到在 native 方法里是获取本机的 hostname,那是否和这个 hostname 有关系呢。

5d1e14ecd59a795394.jpg

这是在我自己的阿里云服务器上测试,真正的测试环境不是这个名字。

拿到服务器 hostname 后再尝试 ping 这个 hostname,奇怪的现象发生了:

命令刚开始会卡住一段时间(大概几十秒),然后才会输出 hostname 对应的 ip 以及对应的延迟。

而当我直接 ping 这个 ip 时却能快速响应后面的输出。

最后我尝试在 /etc/hosts 配置文件中加入了对应的 host 配置:

xx.xx.xx.xx(ip) hostname

再次 ping hostname 的效果就和直接 ping ip 一样了。

于是我再次重启应用,一切都正常了。

总结

最后根据我调整的内容尝试分析下本次问题的原因:

  • Dubbo 在启动获取本地 ip 时,是通过服务器 hostnamedns 服务器返回当前的 ip 地址。
  • 由于 dns 服务器或者是本地服务器与 dns 服务器之间存在网络问题,导致这个过程的时间被拉长(猜测)。
  • 我在本地的 host 文件中配置后,就相当于本地有一个缓存,优先取本地配置的 ip ,避免了和 dns 服务器交互的过程,所以速度提升了。

虽然问题得到解决了,但还是有几个疑问:

第一个是为什么和 DNS 服务器的交互会这么慢,即便是慢也没有像应用那样需要 2 个小时才能返回,这里我也没搞得太清楚,有相关经验的朋友可以留言讨论。

第二就是 Dubbo 在这个依赖外部获取资源时健壮性是否可以做的更好,虽说我这问题估计也几人碰到。

对于这种长时间没有启动成功的问题是否可以加上提示,比如直接抛出异常退出程序,将问题可能的原因告诉开发者,方便排查问题。

你的点赞与分享是对我最大的支持

转载于:https://www.cnblogs.com/crossoverJie/p/11135619.html

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

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

相关文章

React hook 中的数据获取

相关说明: 对于hook相关词不翻译,感觉翻译后怪怪的。 effect hook 效果钩子,用于执行一些副作用例如获取数据 。 state hook 状态钩子。 使用----------- 和 ----------- 标出代码需要关注的地方。 渣翻译如下: 在这个指南中…

嵌入式Jetty和Apache CXF:借助Spring Security来保护REST服务

最近,我遇到了一个非常有趣的问题,我认为这只花了我几分钟就解决了:在Windows Server 2003中使用Spring Security (当前稳定版本3.2.5 )保护Apache CXF (当前版本3.0.1 )/ JAX-RS REST服务。在嵌…

我所知道的前端组件化与模块化

序言:组件化?模块化?这都是什么鬼?这是最初看到这2个新名词的反应。随着时间的推移,似乎、可能、大概明白了一点,于是想说说自己的理解(仅仅是自己的理解) 一、组件化 忘记什么时候看到这个词的了&#x…

关于通过反汇编查看dll的方法【转】(

关于通过反汇编查看dll的方法【转】( http://blog.sina.com.cn/s/blog_51a3c0380100f9md.html 今天想看一个dll的内容,苦于没有相关工具,从csdn上找到有这么段文字,收益匪浅啊,收藏! 可以通过反汇编来知道接口函数的参…

openocd安装与调试

环境&#xff1a; 硬件&#xff1a;PC机<------>ARM仿真器v8.00<------>已下载好bit流的Xinlinx SoC开发板&#xff08;其上有arm cortex-a9核&#xff09; 软件&#xff1a;Redhat Linux6&#xff08;或虚拟机&#xff09; openocd 使用openocd下载程序&#xff…

在React中获取数据

React初学者经常从不需要获取数据的应用开始。他们经常面临一个计数器&#xff0c;任务列表获取井字棋游戏应用。这是很好的&#xff0c;因为在开始学习React的时候&#xff0c;数据获取在你的应用中添加了另一层复杂度。 然而&#xff0c;有些时候你想要从自己的或者第三方AP…

使用Project Lombok减少Java应用程序中的样板代码

对Java编程语言最常提出的批评之一是它需要大量的样板代码 。 对于简单的类尤其如此&#xff0c;该类只需要存储一些值就可以。 您需要这些值的getter和setter&#xff0c;也许您还需要一个构造函数&#xff0c;覆盖equals&#xff08;&#xff09;和 hashcode&#xff08;&am…

DOM之城市二级联动

1、HTML内容 <select id"province"><option>请选择</option><option>山东省</option><option>吉林省</option><option>上海市</option></select><select id"city"><option>请选择…

跳转指令-JMP

page 60,132TITLE A0405Jump(EXE) JMP跳转指令.MODEL SMALL.STACK 64.DATAORG 100H ;规定程序的起始地址A10MAIN PROC NEARMOV AX,00MOV BX,00MOV CX,1A20: ADD AX,01ADD BX,AXSHL CX,1 ;左移一位JMP A20 ;跳转到A20A10MAIN endp jmp格式 [label:] jmp short/near/far/address…

java输出毫秒时间

SimpleDateFormat df new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");// 输出字符串System.out.println(df.format(new Date()));转载于:https://www.cnblogs.com/longchang/p/11139947.html

Three.js制作360度全景图

这是个基于three.js的插件&#xff0c;预览地址&#xff1a;戳这里 使用方法&#xff1a; 1、这个插件的用法很简单&#xff0c;引入如下2个js <script src"js/three.min.js"></script><script src"js/photo-sphere-viewer.min.js">&l…

C++资源库不完全版本

http://www.360doc.com/content/10/0414/20/59141_23072568.shtml boost graph...转载于:https://www.cnblogs.com/seon/archive/2011/08/08/2131246.html

babel6和babel7中关于polyfill和preset-env和babel-plugin-transform-runtime等总结

记录自己零散的收获&#xff0c;随笔。 一些基础 babel的作用是转换JS新的特性代码为大部分浏览器能运行的代码。 babel转码又分为两部分&#xff0c;一个是语法转换&#xff0c;一个是API转换。 对于API的转换又分为两部分&#xff0c;一个是全局API例如Promise&#xff0c…

十六、CI框架之数据库操作get用法

一、使用数据库的Get方法读取内容&#xff0c;如下代码&#xff1a; 二、数据库如下&#xff1a; 二、效果如下&#xff1a; 转载于:https://www.cnblogs.com/tianpan2019/p/11141809.html

使用Spring Boot和Spring MVC自定义HttpMessageConverters

为Spring Boot应用程序或直接的Spring MVC应用程序公开基于REST的终结点很简单&#xff0c;以下是一个控制器&#xff0c;该终结点公开了一个终结点&#xff0c;用于基于其发布的内容创建实体&#xff1a; RestController RequestMapping("/rest/hotels") public cl…

JS如何禁止别人查看网站源码

四种查看路径&#xff1a; 查看效果&#xff1a;猛戳 1、直接按F12 2、Ctrl Shift I查看 3、鼠标点击右键查看 4、Ctrl uview-source: url 把以上三种状态都屏蔽掉就可以了&#xff0c;document有onkeydown(键盘按键事件)&#xff0c;该事件里面找到对应的keycode并处理就…

JS相关知识总结(一)

总结下这段时间吸收的许多小知识&#xff0c;以备忘记后翻阅。 关于面向对象 面向对象特征&#xff1a; 具有唯一标识性具有状态具有行为 JS的面向对象和JAVA的实现思路不一样&#xff0c;JS是基于原型并非基于类。但是JS为了看起来更像JAVA&#xff0c;为此添加了一些特性…

WCF系列(二) -- 使用配置文件构建和使用WCF服务

当然&#xff0c;配置一个ServiceHost除了上面说的完全使用代码的方式&#xff0c;更好的方式是使用配置文件&#xff0c;把一些可能需要修改的属性跟代码分离&#xff0c;放到配置文件中&#xff0c;这样可以提供服务配置的灵活性&#xff0c;也更容易维护。 看看前面那个不用…

java读取文件方法

一、多种方式读文件内容。1、按字节读取文件内容2、按字符读取文件内容3、按行读取文件内容4、随机读取文件内容 Java代码 import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileReader; import java.io.IOExcept…

如何使用github搭建个人博客

1、去github官网注册个人帐号&#xff1a;没有的&#xff1a;猛戳这里去注册&#xff0c;比如我的账户名&#xff1a;wjf444128852&#xff0c;我的已经汉化(可在github里搜索github如何汉化有插件) 2、点击仓库-新建&#xff0c;仓库名字必须是&#xff1a;你的github帐号.git…