线上应用调试利器 --Arthas

  在之前的文章中,我介绍了使用 Btrace 工具进行线上代码的debug (https://www.cnblogs.com/yougewe/p/10180483.html),其大致原理就是通过字节码注入的方式进行辅助排查。

  可以说,btrace 已经给我们的开发调试一带来了许多的方便,我们在上面做任何想要的调试!但是,明显, btrace 的使用还是有一定成本的,比如:安装应用,写调试脚本...

  所以,今天我们再来看一大利器: arthas (阿尔萨斯)

arthas 官网地址:https://alibaba.github.io/arthas/

  arthas 的文档真的写得非常棒,可以说一看就会。

但是我还是想写一下一些自己的文档,毕竟我们往往只会用到其中皮毛功能而已。翻阅其所有文档也还是有点浪费了!

一、为什么要用 Arthas ?

  其实,这个问题在前面已回答,而且,你为什么要用 btrace ? 同理! 具体理由如下:

  1. 可以很方便查到一类是从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
  2. 怀疑自己的代码未被部署到服务器,可以通过命令快速验证服务器上的代码就是本地的代码;
  3. 可以直接通过 arthas 进行线上debug, 查看方法返回值以确认问题所在;
  4. 可以很方便嵌入自己的debug代码,快速验证猜想;
  5. 操作完成后,可以将所有debug代码删除,从而避免影响线上运行;

二、如何安装?

  真的是超级简单哦;1. 先把 arthas  的 工具jar包下载下来; 2. 运行即可;

wget https://alibaba.github.io/arthas/arthas-boot.jar
java -jar arthas-boot.jar

  请问,还能更简单吗?

三、如何解决问题?

  经过上一步安装,并运行之后,就差不多是图形界面操作了。

  第一步,arthas 会检测到目前正在有几个运行中的java程序,你只需按照序号选择就就可以了。这里你就完全置身该应用环境了。接下来就可以 do what ever you want to do 。

下面,我以几个常用问题场景,来简要看看其解决方案如何吧!

问题1. 我如何查找某个只知道大概的类,或者说我想确认某个类是否已被系统加载?

  通过这个问题,我们可以确认一点: 我写的代码是否被部署了。当然,如果是对于 war 包,其实这个问题比较容易解决,因为它是一个个的 class 文件,我们可以直接使用 find 命令查找即可。然而这毕竟只是理想,事实会很复杂!

  所以, arthas 怎么查找一个类?

sc *DispatcharServlet      # 即可以找到需要的类全路径,如果存在的话
sm org.springframework.web.servlet.DispatcherServlet getHandler # 查看某个方法的信息,如果存在的话 

  甚至我们可以使用通配符列出所有的方法:

问题2.  如何查看一个class类的具体信息?

  虽然通过上面检查类和方法是否存在,能够解决一部分我们排查代码的问题,但是在我们只是改动一个方法中的稍稍逻辑时,就无法通过类和方法来确认问题,此时就需要进行反编译后进行查看了!

  这事如果要我自己去干,我多半只是将jar包中的class文件,使用 javap 进行反编译成可读字节码,然后很认真地核对类信息! javap 虽然已经在很大程度上减轻了我们的阅读压力,但仍然门槛很高。

  而 使用 arthas 则简单至极:

jad org.springframework.web.servlet.DispatcherServlet # 直接反编译出java 源代码,包含一此额外信息的

问题3. 如何跟踪某个方法的返回值、入参.... ?

  这个问题其实是我们在用 btrace 这样的工具的大部分时候的初衷!虽然 trace 脚本编写并不复杂,但是千篇一律和频繁地更改,也给我们带来了许多麻烦。

  而这在 arthas 就是一个命令的事!

watch com.test.ob testMethod "{params, returnObj, throwExp}" -e -x 2  # 同时监控入参,返回值,及异常

  如果有异常,直接打印出来,否则出入参直接监控,超级方便!

  这里有支持复杂的 ognl 语法,实现更复杂逻辑,请参考: https://alibaba.github.io/arthas/watch.html

问题4. 查看最繁忙的线程,以及是否有阻塞情况发生?

  查看繁忙的线程,一般我们可以通过 top 等系统命令进行查看,但是那毕竟要很多个步骤,很麻烦。

  而 arthas 则直观明了:

thread -n 3 # 查看最繁忙的三个线程栈信息
thread  # 以直观的方式展现所有的线程情况
thread -b #找出当前阻塞其他线程的线程

问题5. 如何验证自己的代码猜想,临时更改代码运行?

  可能我就是认为其中有一个数字写错了,导致业务出错,但是不太确认,所以想在线上直接验证下!

  基本的经验是,在本地改了代码后,重新打包部署,然后重启观察效果。但是这太慢了!

jad --source-only com.example.demo.arthas.user.UserController > /tmp/UserController.java  # 先反编译出class源码
 # 然后使用外部工具编辑内容
mc /tmp/UserController.java -d /tmp  # 再编译成class
 # 最后,重新载入定义的类,就可以实时验证你的猜测了
redefine /tmp/com/example/demo/arthas/user/UserController.class

  如上,是直接更改线上代码的方式,但是一般好像是编译不成功的。所以,最好是 本地ide 编译成 class 文件后,再上传替换为好!

  总之,已经完全不用重启和发布了!

问题6. 我如何测试某个方法的性能问题?

  这个问题其实我们一般不太关注,但是当性能成为问题时,则真的要关注了!平时我们使用 进入打印开始时间,退出打印一个结束时间这种方式,还是有点low了!

monitor -c 5 demo.MathGame primeFactors

  以上命令直接统计 primeFactors 的响应问题:

  更多参考:https://alibaba.github.io/arthas/monitor.html

问题7. 更高级的追踪工具!

  tt (T)

  trace

  其实,我们排查问题时,总是费尽周折。然而当问题解决时,又发现简单到不行。

阿里老话:结果很重要,过程也很重要!

原文地址:https://www.cnblogs.com/yougewe/p/10770690.html

时间: 2024-07-31 20:59:17

线上应用调试利器 --Arthas的相关文章

线上问题排查利器Arthas

官方文档 下载arthas-boot.jar,然后用java -jar的方式启动: curl -O https://alibaba.github.io/arthas/arthas-boot.jar java -jar arthas-boot.jar 执行该程序的用户需要和目标进程具有相同的权限.比如以admin用户来执行:sudo su admin && java -jar arthas-boot.jar 或 sudo -u admin -EH java -jar arthas-boot.

java线上问题调试

线上出现问题,如oom等问题,可以将堆hprof文件使用java VisualVM打开堆文件 可以看到最多的对象是char数组,可以看出来 从这些对象中可以看到相应的信息,根据这些信息查看相应的问题 原文地址:https://www.cnblogs.com/zhangchiblog/p/9319921.html

线上防雪崩利器——熔断器设计原理与实现

前言 这是一篇根据工作中遇到的问题总结出的最佳实践. 上周六,我负责的业务在凌晨00-04点的支付全部失败了. 结果一查,MD,晚上银行维护,下游支付系统没有挂维护公告,在此期间一直请求维护中的银行,当然所有返回就是失败了,有种欲哭无泪的感觉,锅让业务来背. 为了杜绝在此出现这种大面积批量的支付失败情况发生,保障系统的健壮性.我需要个在集中性异常的时候可以终止请求,当服务恢复,恢复请求. 我想了一些方式,最后,觉得熔断器比较适合干这种事情. 状态模式 我们已一个开关为例 在每一种状态下,cont

调试工具-fiddler:本地资源替换线上调试

Fiddler是一个http协议调试代理工具,它能够记录并检查所有你的电脑和互联网之间的http通讯,设置断点,查看所有的“进出”Fiddler的数据(指cookie,html,js,css等文件,这些都可以让你任意替换线上进行修改的意思),用线下的文件替换线上的进行修改调试,的确很方便. (一)官方地址 http://www.telerik.com/fiddler (二)下载后的界面,选中“AutoResponder”,然后下面的三项全打钩,如图: (三)在浏览器打开一个线上页面,如太平洋汽车

fiddler修改线上的内容

有时候本地的代码跟线上的代码还是运行环境还是有区别的.比如有些封装的方法需要运动到手机上可以调试,而浏览器是无法调试的.如果不想每次修改完再放上到测试环境看效果,那要怎么做呢?fiddler为我们提供了很多的便利,直接就可以让你通过本地的代码,来让线上马上就可以访问到.来来来,走起 操作如下:(图片发布到线上变形了,抱歉,不过基本可以看懂) 第一步:打开你需要替换的内容网站,找到你要替换的内容 比如我想替换博客园右边栏的那张广告图片,不错,我就是看不惯这个广告,所以我想把这个图给换掉.你可以在谷

前端开发调试线上代码的两款工具

用过 Charles 和 Fiddler 这两款,记录如下. 一.Charles Charles 界面简单直观,易于上手,数据请求控制容易,修改也简单,抓取数据的开始暂停也方便.支持 win,mac,linux. 1. 安装前提Charles 需要有 Java 环境,请提前下载安装 JDK.JDK 已经 8 了. 根据自己的系统选择对应的JDK.我的是 win7,双击安装,一直下一步就哦了.在命令行窗口输入以下命令,出现截图所示就表示 JDK 安装成功了 2. 下载 Charles Charle

Fiddler调试线上JS代码

强力推荐一款js调试神器,Fiddler 大家平时肯定都用过火狐的Firebug或者谷歌的调试工具来调试JS,但遗憾的是我们不能像编辑html,css那样来直接新增或者删除JS代码. 虽然可以通过调试工具的控制台来动态执行JS代码,但有时候却远远不够用. 特别是当产线环境不能随意修改文件情况下,用线上环境来调试本地代码更是迫切的需求. (往往本地测试通过,上线后却是各种bug.) 今天分享一下如何用Fiddler来修改并调试线上的JS代码. 以博客园首页为例子,用我本地的一个js文件来替换它的一

chrome浏览器调试线上文件映射本地文件

通过ReRes让chrome拥有路径映射的autoResponse功能. 前端开发过程中,经常会有需要对远程环境调试的需求.比如,修改线上bug,开发环境不在本地等等.我们需要把远程css文件或者js映射到本地的文件上,通过修改本地文件进行调试和开发.通常我们可以通过以下方法来实现映射: 1.修改host文件——只能把域名映射到IP 2.使用Apache或者nginx搭建反向代理——需要装环境,配置相对繁琐 3.使用Fiddler中的AutoRespnose功能——不支持目录映射,mac.lin

调试利器GDB(上)

调试利器GDB(上) 1.1 GDB初识 1.1.1什么是GDB? GDB是GNU项目中的调试器(gnu debuger),能够跟尊程序的执行,也能恢复程序崩溃前的状态 1.1.2为什么需要GDB? 软件产品的研发过程必然伴随bug,调试时软件开发中不可或缺的技术(调试工具很重要) 1.1.3 DBG与binutils 1.2 GDB的常规使用 1.自定义程序得到启动方式(指定影响程序运行的参数)2.设置条件断点(在满足条件时程序暂停执行)3.回溯检查导致程序异常结束的原因(core dump)