云计算

当Dubbo遇上Arthas:排查问题的实践

Apache Dubbo是阿里巴巴开源的高级RPC框架,在国内有非常多的用户。

  • GitHub:https://github.com/apache/incubator-dubbo
  • 文档:http://dubbo.incubator.apache.org/zh-cn/

Arthas是阿里巴巴开源的应用诊断利器,9月份开源以来,Github Star数三个月超过6000。

  • GitHub:https://github.com/alibaba/arthas
  • 文档:https://alibaba.github.io/arthas/
  • 阿尔萨斯开源交流QQ群:916328269
  • Arthas开源交流钉钉群:21965291

当Dubbo遇上Arthas,会碰撞出某种形式的火花呢?下面来分享Arthas排查Dubbo问题的一些经验。

dubbo-arthas-demo

下面的排查分享基于这个,非常简单的一个应用,浏览器请求从Spring MVC到Dubbo Client,再发送到Dubbo Server。dubbo-arthas-demo

Demo里有两个spring boot应用,可以先启动,再启动。server-democlient-demo

  • https://github.com/hengyunabc/dubbo-arthas-demo

客户端:

服务器端:

阿尔萨斯快速开始

  • https://alibaba.github.io/arthas/install-detail.html

启动后,会列出所有的java进程,选择1,然后回车,就会连接上 ServerDemoApplication

Dubbo线上服务引发异常,如何获取调用参数?

  • https://alibaba.github.io/arthas/watch.html

当线上服务引发异常时,最着急的是什么参数导致了抛异常?

在demo里,访问http:// localhost:8080 / user / 0,UserServiceImpl就会引发一个异常,因为user id不合法。

在Arthas里执行,然后再次访问,就可以看到watch命令把参数和异常都打印出来了。

如何调试Dubbo服务代码?

  • https://alibaba.github.io/arthas/redefine.html

在本地开发时,可能会用到热部署工具,直接改写代码,不需要重启应用。但是在线上环境,有没有方法直接动态调试代码?

在Arthas里,可以通过redefine命令来达到线上不重启,动态更新代码的效果。

例如我们修改下UserServiceImpl,用打印出具体的对象来:

本地编绎后,把传到线上服务器,然后用命令来更新代码:

这样子更新成功之后,访问http:// localhost:8080 / user / 1,在ServerDemoApplication的控制台里就可以看到打印出了用户信息。

怎样动态修改Dubbo的logger等级?

  • https://alibaba.github.io/arthas/ognl.html
  • https://alibaba.github.io/arthas/sc.html
  • https://commons.apache.org/proper/commons-ognl/language-guide.html

在排查问题时,需要查看到更多的信息,如果可以把loggergrade修改为DEBUG,就非常有帮助。

ognl是apache开源的一个轻量级表达式引擎。下面通过Arthas里的ognl命令来动态修改logger等级。

首先获取Dubbo里TraceFilter的一个logger对象,看下它的实现类,可以发现是log4j。

再用sc命令来查看具体从该哪个jar包里加载的:

可以看到log4j是通过slf4j代理的。

那么通过获取logger,再修改它的级别:

可以看到修改之后,rootlogger的级别转化DEBUG

怎样减少测试小姐姐重复发请求的麻烦?

  • https://alibaba.github.io/arthas/tt.html

在平时开发时,可能需要测试小姐姐发请求过来联调,但是我们在调试时,可能不小心直接跳过去了。这样子就尴尬了,需要测试小姐姐再发请求过来。

Arthas里提供了tt命令,可以减少这种麻烦,可以直接重新请求。

上方的命令捕获到了3个请求。然后通过可以重新初始化请求:

Dubbo运行时有一些过滤器?耗时是多少?

  • https://alibaba.github.io/arthas/trace.html

Dubbo运行时会加载很多的过滤器,那么一个请求会经过某种过滤处理,过滤里的耗时又是多少呢?

通过Arthas的trace命令,可以很方便地知道Filter的信息,可以看到详细的调用栈和耗时。

Dubbo动态代理是怎样实现的?

  • https://alibaba.github.io/arthas/jad.html
  • com.alibaba.dubbo.common.bytecode.Wrapper

通过Arthas的jad命令,可以看到Dubbo通过javaassist动态生成的Wrappr类的代码:

获取Spring上下文

除了上面介绍的一些排查技巧,下面分享一个获取Spring Context,然后“为所欲为”的例子。

在Dubbo里有一个扩展,把Spring Context保存到了里面。因此,我们可以通过命令获取到。

下上面的语句:

  • SpringExtensionFactory@contexts.iterator.next 获取到  SpringExtensionFactory里保存的spring context对象
  • #context.getBean("userServiceImpl").findUser(1) 获取到  userServiceImpl再执行一次调用

只要充分发挥想像力,组合Arthas里的各种命令,就能发挥出神奇的效果。

总结

本篇文章来自杭州Dubbo Meetup的分享《当DUBBO遇上Arthas-排查问题的实践》,希望对大家在线排查Dubbo问题有帮助。

分享的PDF可以在https://github.com/alibaba/arthas/issues/327里下载。

我还没有学会写个人说明!

百度大规模时序数据存储(一)| 监控场景的时序数据

上一篇

软通智慧携手华为:在智慧城市领域,更凸显生态的作用

下一篇

你也可能喜欢

当Dubbo遇上Arthas:排查问题的实践

长按储存图像,分享给朋友

ITPUB 每周精要将以邮件的形式发放至您的邮箱


微信扫一扫

微信扫一扫