3

Junit4 一直处于运行中的排查过程 - 锅叔

 1 year ago
source link: https://www.cnblogs.com/uncleguo/p/17510987.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Junit4 一直处于运行中的排查过程

  新买了一个Macbook Pro . 之前的工程搬家过来, 这天要跑个单元测试。 发现Junit4 一直处于运行中。没有错误信息,没有用例执行结果。遂开始排查原因。

  这里插一句,苹果芯片的Mbp还是很好用的,除了性能够用之外,最主要是安静+不热。 这对比我之前的i7版本的真是太明显了。 之前的i7在外接显示器的情况下,风扇狂转,还降频。苹果抛弃Intel还是有道理的。

  回正题, 这类比较诡异问题的排查,一般思路就是猜+试 ,但试和猜的逻辑要清晰。本文主旨也是在于思路总结。

  一、测试类是不是写的有问题?

  很好排查,跑跑其他之前写的测试类, 果然也不好用了。 说明跟具体的测试类无关。

  二、是工程的问题还是我自身环境的问题?

  小X, 我这儿为啥跑不了单元测试了。 你试试能跑了。 小X: “我这里可以跑,没问题”。 可见应该跟我的环境配置有关。 

  ——持续在执行中,且没有错误,并且与个体环境有关。 如果有经验的同学,很容易想到,这可能说明,测试过程在正常执行,只是非常缓慢。环境相关的性能问题,往往与网络有关。

  三、化简工程后,是否正常工作?

  实际项目的工程往往比较复杂, 管理的Bean动辄,几百上千。 这些Bean可能有各种初始化方法, 阻塞了程序的启动,导致了Junit 卡在Spring上下文建立的过程中。测试过程就无法开始运行。

  因此,缩小扫描路径范围, 对一个依赖其他Bean较少的Bean做单元测试。 发现执行正常。

  ——这说明应该确实是卡在了某些Bean的创建过程中

  四、缩小范围

  从上面的试验结果很容易想到,如果逐步将Beans加入到扫描路径,就可以定位出具体是哪个Bean引起的阻塞问题。经过尝试发现,工程用到了dubbo,其中的 provider service 越少,@Test执行的越快,当多到一定程度时,

  就会表现为,一直处于运行中的状态了。

  ——这里已经可以定位到,导致问题的表面原因了。猜测可能是dubbo与注册中心的网络通信过程,造成的影响。

  五、 源码调试

  开源的好处是,源码之前了无秘密,但通常源码也没那么容易看懂 o(* ̄︶ ̄*)o。 跟了一段执行过程的源码,暂时没有发现明确的原因

  ——源码面前了无秘密肯定是真理,耐心跟一定会发现原因的。

  六、柳暗花明

  跟源码跟的不耐烦之际,觉得这么调有点费劲。想在忙碌的过程中直接调试器暂停执行,也许会断到引起阻塞的问题代码附近。于是,重新调试执行测试,在等待一段超出正常范围的时间后,按下调制器的暂停。

  通过调用栈往上找找,果然是在dubbo的包内。观察了下附近有一个非常可疑的。

InetAddress.getLocalHost().getHostAddress()

  ChatGpt了下,Gpt说:
  注意:在生产环境中,反复调用 InetAddress.getLocalHost().getHostAddress() 是不推荐的,因为这可能是一个耗时的操作。通常,获取本地IP地址是一个一次性的任务,应该在应用程序启动时执行,并缓存结果以供后续使用。

  然后阅读了附近的源码,发现dubbo当取得prodiver 的hostip 是 127.0.0.1 或者 localhost 时。会调用这个方法, 取得一个网络上的IP。(例如192.168.1.X之类)。

  尝试将prodiver 的 host 从 127.0.0.1  配置为 网络IP后, 问题解决。

  总结:

  问题的原因是当provider host配置为 127.0.0.1 时,会调用耗时操作。 当provider 提供的service 很多时。就会成倍放大这个耗时操作的时间。这个原因跟猜测,以及经验,现象都是能相互验证的。

  宝贵经验:

  1. InetAddress.getLocalHost().getHostAddress()  是一个耗时操作,在某些网络环境下可能非常慢。

  2.今后遇到这种一直执行中不报错的情况,应该直接点暂停,读源码 -_-||。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK